> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryrollup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Common Rollup SDK errors, what they mean and how to fix them.

Every error the SDK throws is a `RollupError` with a stable `code` and a `message` meant for you, not for the person. Errors from Rollup's server carry the server's error code at the start of the message. See [RollupError](/reference/rollup-error) for every code.

```swift theme={null}
do {
    let answer = try await Rollup.shared.query("Where do I eat most?")
} catch let error as RollupError {
    print(error.code, error.message)
}
```

<AccordionGroup>
  <Accordion title="simulatorUnsupported">
    `configure` throws this in the iOS Simulator. The SDK needs a real iPhone with iOS 26 or later: Apple Vision analysis does not run in the Simulator. Your app still builds for the Simulator; skip Rollup there and test it on a device.

    ```swift theme={null}
    #if !targetEnvironment(simulator)
    try Rollup.configure(publishableKey: "rk_live_...")
    #endif
    ```
  </Accordion>

  <Accordion title="missingRequirement">
    `configure` throws this when your Info.plist lacks an entry the SDK needs. The message names each one: `NSPhotoLibraryUsageDescription`, the two `BGTaskSchedulerPermittedIdentifiers` entries, or `processing` in `UIBackgroundModes`. See the [Quickstart](/quickstart#configure-your-app-target).
  </Accordion>

  <Accordion title="notConfigured">
    Call `Rollup.configure(publishableKey:indexing:)` before any other call. `configure` also throws this when the key does not start with `rk_`.
  </Accordion>

  <Accordion title="appPendingApproval: the app is waiting for approval">
    Your app exists in the dashboard but Rollup has not approved it yet, so the server answers every request with 403 `app_pending`. The SDK throws `appPendingApproval` and reports the state `.failed` with it while nothing is running. Indexing that needs the server waits; search over an index already on the iPhone keeps working. The SDK does not lock, and asks again at its next check: at launch, at the start of a background run, or once a day. Check your app's status in the [dashboard](https://www.tryrollup.com/developers).
  </Accordion>

  <Accordion title="accessRevoked">
    Your app's key stopped working: the key is unknown or past its grace period, the app is disabled or revoked, or your developer account is not approved. The SDK stops indexing, keeps the index locked, and unlocks when access returns. See [Keys and revocation](/guides/keys-and-revocation).
  </Accordion>

  <Accordion title="quotaExceeded: the monthly token budget is used">
    The server answers `query` and `profile` with 429 `app_quota_exceeded`, and the SDK throws `quotaExceeded`, without retrying. `query` and `profile` stop until the first day of the next month (UTC), or until Rollup raises your app's budget. The message names the reset date. Search and indexing keep working. See [Limits and budgets](/guides/limits-and-budgets).
  </Accordion>

  <Accordion title="rateLimited">
    A device or your app sent too many requests in 5 minutes (429 `rate_limited`). The SDK throws `rateLimited`, which is retryable; wait `retryAfter` seconds when it is set, or a little while, and try again. See [Limits and budgets](/guides/limits-and-budgets).
  </Accordion>

  <Accordion title="appAttestFailed: device registration fails">
    The SDK registers each install with Rollup the first time it needs the server, with an App Attest attestation. `appAttestFailed` means App Attest could not vouch for this install, and its message names the likely cause. Check that:

    * your target has the **App Attest** capability (`com.apple.developer.devicecheck.appattest-environment`), which `configure` cannot check,
    * the Team ID and bundle ID of your app in the dashboard match the build you are running,
    * you are on a real iPhone, not the Simulator.

    Development-signed and App Store builds both work: Rollup accepts the development and production App Attest environments. When Apple's App Attest service is unavailable, the SDK throws a retryable `network` error instead; try again later.
  </Accordion>

  <Accordion title="noIndex">
    Search, query and profile have nothing to read yet. Wait until `Rollup.shared.indexing.state.isSearchable` is true. If the state is `needsPhotoAccess`, call `requestPhotoAccess` first.
  </Accordion>

  <Accordion title="photoAccessDenied, or the state stays needsPhotoAccess">
    The person declined Photos access, or turned it off in Settings. Without access the SDK indexes nothing and deletes an index it already had, so `search`, `query` and `profile` throw `photoAccessDenied` and the state is `needsPhotoAccess`. `requestPhotoAccess` still returns the person's answer. Ask the person to allow access in Settings. Limited access is not denied: the SDK indexes the photos the person shared.
  </Accordion>

  <Accordion title="assetsUnavailable">
    The first-run models could not be downloaded. Check the network; with `allowsCellular` set to `false`, the download waits for Wi-Fi. The SDK retries on the next run and resumes where it stopped.
  </Accordion>

  <Accordion title="Indexing stops when the app leaves the screen">
    Indexing continues in the background only when the person started it: through the Photos grant in `requestPhotoAccess`, or through `indexing.start()` called from a tap. Other runs stop safely when your app leaves the screen, and the SDK finishes the index later in a background processing task or the next time your app is on screen. See [Background indexing](/guides/background-indexing).
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.