---
title: SDK troubleshooting
description: Diagnose emulator connections, login callbacks, access errors, and duplicate submissions.
---

# SDK troubleshooting {#sdk-troubleshooting}

## Test with the emulator {#test-with-the-emulator}

The sample app in the SDK repository checks the local server and SDK flow. Register `opentester-sample://callback` for the app in the local developer console and approve the tester's enrollment.

With Android SDK and JDK installed, run:

```sh
cd opentester-android-sdk
./gradlew :opentester:testDebugUnitTest :sample:assembleDebug
adb install -r sample/build/outputs/apk/debug/sample-debug.apk
```

If `adb` is not on PATH, use `platform-tools/adb` from the Android SDK. The sample defaults to web `http://10.0.2.2:3000` and API `http://10.0.2.2:4000`. Include that web origin in the API's allowed origins.

1. Enter the app ID from the console.
2. Open browser login and sign in with the approved **tester account**.
3. Approve the app connection and return to the sample.
4. Check access and submit a bug or feedback.
5. Verify the report in the developer console.

For a USB-connected physical device, run these commands and use `http://localhost:3000` and `http://localhost:4000`:

```sh
adb reverse tcp:3000 tcp:3000
adb reverse tcp:4000 tcp:4000
```

Only the debug manifest allows local HTTP and the custom callback. Configure [HTTPS App Links](/sdk/authentication) for distributed apps.

## Login opens but does not return to the app {#login-opens-but-does-not-return-to-the-app}

- Match the console callback, `OpenTesterConfig.redirectUri`, and manifest host/path.
- Check the installed app's application ID and signing certificate in `assetlinks.json`.
- The callback Activity must be `exported="true"` and declare `VIEW`, `DEFAULT`, and `BROWSABLE`.
- The sample custom scheme is for local development; production requires HTTPS callbacks.

## No pending login or invalid state {#no-pending-login-or-invalid-state}

Handle the callback with the same SDK instance that started login. Keep it in `Application` or another retained object. Restart login after process termination.

Consume the callback once and clear the Intent's `data`. Repeated `createAuthenticationUri()` calls replace pending state. Restart login after callback exchange errors or cancellation.

## 401 or 403 responses {#401-or-403-responses}

| Response | Check |
| --- | --- |
| `401` | Code expired/already used, or token expired; sign in again |
| `403` | Enrollment for this app must be `approved` |

The device browser may use a different account than your desktop. Do not confuse the app owner with the tester. Google Group membership alone does not grant SDK access. Requests should fail after approval is revoked; `401` and `403` also clear the SDK's in-memory session.

## Network errors or invalid responses {#network-errors-or-invalid-responses}

- Do not append `/api/v1` to `apiBaseUrl`.
- Set `webBaseUrl` to the website, not the API.
- Use `10.0.2.2` to reach the host machine from an Android emulator.
- Local HTTP requires both `allowInsecureLocalhost = true` and Android debug network security configuration. Arbitrary LAN HTTP addresses are not allowed.
- Check whether a proxy redirects requests or returns an HTML login page. SDK requests do not follow redirects.

Connection timeout is 10 seconds; read timeout is 15 seconds. Offline access checks must not be treated as successful.

## A retry returns the same report {#a-retry-returns-the-same-report}

The same app, tester, and `clientRequestId` return the existing report, even if the content changed. Use a new UUID for a new report and the original UUID for retries. If duplicates appear, check whether you recreate `BugReport` or `FeedbackReport` on every attempt. See [retries](/sdk/feedback#retry).

## Errors are not submitted automatically {#errors-are-not-submitted-automatically}

Call `submitBug()` or `submitFeedback()` to send text. Uncaught-exception capture, automatic crash reports, attachments, session recording, and offline queues are not implemented.

## Maven dependency cannot be found {#maven-dependency-cannot-be-found}

Use `app.opentester:android-sdk:0.1.0` and include `mavenCentral()` in `settings.gradle.kts`. The Kotlin package `dev.opentester.sdk` is different from the Maven group ID. For JitPack, use `https://jitpack.io` and `com.github.opentesterapp:opentester-android-sdk:v0.1.0` together.

## Release build cannot find SDK classes {#release-build-cannot-find-sdk-classes}

`debugImplementation` makes the SDK unavailable in release builds. Put test Activities, Application classes, and manifests in `src/debug/` or the test flavor's source set, and inject build-specific implementations into shared code. The sample is an SDK verification app, not a general-release template.
