iOS · Android · SDK

# Troubleshooting

Find the cause when configuration fails, requests are rejected, or content does not appear in your app.

## Start here

1. The SDK key and the content belong to the same app in [Mobile Joe](https://app.mobilejoe.dev/).
2. `Joe.configure` runs at app start, before any Mobile Joe screen appears.
3. [App Settings → Set up SDK](https://app.mobilejoe.dev/setup) confirms a registered device of your platform.
4. The content is live, targeted at your device, and in the selected list filter; see [Content delivery](https://docs.mobilejoe.dev/sdk/content-delivery.md).
5. The [SDK logs](https://docs.mobilejoe.dev/sdk/troubleshooting.md#logs) show no error.

## Initialization

- **Screens load too early:** configure in the `App` initializer on iOS and directly in `Application.onCreate` on Android. Configuring in `.task` or a coroutine lets a screen load first: iOS shows “Sorry! Something went wrong.”, Android “Something went wrong!”, and `AlertsView` misses an active alert.
- **Not configured:** iOS throws `MobileJoeError.notConfigured`, Android an `IllegalStateException`.
- **Configuration errors:** `configure` rejects an empty app user ID and fails when the identity cannot be stored. Replace the quickstart's `try?` with `do`/`catch` to see the error on iOS; Android logs it with the tag `Joe`.
- **Android:** register your `Application` class in the manifest with `android:name`. `StrictMode` disk-access warnings from `configure` are expected.

## Rejected requests

| Status | Cause | Fix |
| --- | --- | --- |
| 401 | Unknown or missing SDK key | Copy the key again from [Set up SDK](https://app.mobilejoe.dev/setup); check for whitespace and a key of another app. |
| 403 | No API access | Verify the account's email address and keep a trial or subscription active. |
| 429 | Rate limit exceeded | Wait a minute; avoid configuring or voting in a loop. |

A 401 disables the SDK until the app restarts with a valid key: iOS throws `MobileJoeError.invalidAPIKey`, then `notConfigured`; Android throws `JoeInvalidApiKeyException`, then `IllegalStateException`. Other statuses surface as `MobileJoeError.httpFailure` or `JoeHttpException` with status, method, and path.

## Missing content

| Symptom | Check |
| --- | --- |
| No FAQs | The FAQ is live, not a draft or archived. |
| No alerts | Alert views hide errors, so check the [logs](https://docs.mobilejoe.dev/sdk/troubleshooting.md#logs) first. Then check that the alert is live and targets your exact app and OS version. On iOS, wait 15 minutes or use [debug mode](https://docs.mobilejoe.dev/sdk/content-delivery.md#debug-mode). |
| Feature plan missing | The selected filter includes its status; closed plans are never listed. |
| Changes do not appear | Pull to refresh or reopen the screen. The SDKs do not poll. |
| Original text instead of a translation | A translation exists for a requested language; see [Localization](https://docs.mobilejoe.dev/sdk/localization.md). |
| Votes disappear after sign-in or sign-out | Votes belong to the identity; see [Identity and data](https://docs.mobilejoe.dev/sdk/identity.md). |

An empty FAQ or Feature Plan list without an error means the request succeeded and returned nothing. Previews and sample data never confirm the connection.

## Logs

**iOS:** filter Xcode's console or Console.app for `subsystem:MobileJoe`. The standard screens do not log their errors; load a model yourself, for example `try await FAQs().load()`, and log what it throws.

**Android:** filter Logcat for the tag `Joe`. The Compose screens log under their view model's tag, for example `Error loading alerts` from `AlertsViewModel`. SLF4J warnings about missing providers at the first request are harmless; add `runtimeOnly("org.slf4j:slf4j-nop:2.0.20")` to silence them.

Messages to look for:

- “SDK configured successfully.”
- “Failed to identify … Retrying on next app start.”: the identify request failed; the SDK stays usable.
- “Invalid API key. The SDK is disabled until the app restarts with a valid key.”
