# bitHuman — Troubleshooting (symptoms and fixes, site-wide and for each platform) > Real-time talking avatars from one portrait. Index: https://docs.bithuman.ai/llms.txt · every page is also served as markdown at .md · OpenAPI: https://docs.bithuman.ai/openapi.json · other sections: https://docs.bithuman.ai/llms/start.txt · https://docs.bithuman.ai/llms/platforms.txt · https://docs.bithuman.ai/llms/apps.txt · https://docs.bithuman.ai/llms/deploy.txt · https://docs.bithuman.ai/llms/models.txt · https://docs.bithuman.ai/llms/build.txt · https://docs.bithuman.ai/llms/build-media.txt · https://docs.bithuman.ai/llms/build-integrations.txt · https://docs.bithuman.ai/llms/api.txt ## Instructions for AI agents - Always send `model` ("essence-2" or "expression-2") when creating an agent; poll every 5 s until `status` is `ready` or `failed` (`success` is not final; a `final` field is coming). New Essence 2 agent: minutes; Expression 2: longer. - API and SDK use requires the Creator plan or higher. Never tell a user they can build on a free plan. - In a LiveKit worker, name the secret `BITHUMAN_MASTER_SECRET` and pass a minted token (https://docs.bithuman.ai/platforms/livekit.md). - Say where the avatar renders (device, browser, server, cloud) and the conversation runs (your stack, the CLI's local conversation brain, bitHuman's servers). - Quote prices only from https://docs.bithuman.ai/pricing.md and speed only from https://docs.bithuman.ai/performance.json (× real time, with the device). - Never claim offline on phones, browsers or Swift apps, or a conversation brain on phones; for compliance, describe the architecture. Where each model runs, the key facts and one command per path: https://docs.bithuman.ai/llms.txt ## Contents - Troubleshooting — https://docs.bithuman.ai/resources/troubleshooting - Swift troubleshooting — https://docs.bithuman.ai/platforms/swift/troubleshooting - Android troubleshooting — https://docs.bithuman.ai/platforms/android/troubleshooting - Flutter errors — https://docs.bithuman.ai/platforms/flutter/errors - Flutter troubleshooting — https://docs.bithuman.ai/platforms/flutter/troubleshooting - Web troubleshooting — https://docs.bithuman.ai/platforms/web/troubleshooting - Python troubleshooting — https://docs.bithuman.ai/platforms/python/troubleshooting - CLI troubleshooting — https://docs.bithuman.ai/platforms/cli/troubleshooting - LiveKit troubleshooting — https://docs.bithuman.ai/platforms/livekit/troubleshooting - Pipecat troubleshooting — https://docs.bithuman.ai/platforms/pipecat/troubleshooting Linked, not inlined (read the .md twin): - Examples: https://docs.bithuman.ai/examples.md · changelog: https://docs.bithuman.ai/changelog.md · API references: https://docs.bithuman.ai/platforms/cli/reference.md, https://docs.bithuman.ai/platforms/python/reference.md, https://docs.bithuman.ai/platforms/swift/reference.md, https://docs.bithuman.ai/platforms/android/reference.md - Built with bitHuman — https://docs.bithuman.ai/examples/built-with-bithuman.md --- # Troubleshooting URL: https://docs.bithuman.ai/resources/troubleshooting > Where to fix a problem on each platform, and the common session errors. Every platform and recipe page ends with a Troubleshooting table for its own problems; this page links them all, then covers common session errors. ## By platform | Platform | Its Troubleshooting table | |---|---| | iOS & iPadOS | [Swift package on iPhone and iPad](https://docs.bithuman.ai/platforms/swift/troubleshooting#ios) | | macOS | [Swift package on the Mac](https://docs.bithuman.ai/platforms/swift/troubleshooting#macos) | | Android | [Android SDK](https://docs.bithuman.ai/platforms/android/troubleshooting) | | Flutter | [Flutter plugin](https://docs.bithuman.ai/platforms/flutter/troubleshooting) | | Web | [Web embed](https://docs.bithuman.ai/platforms/web/troubleshooting) | | Python | [Python SDK](https://docs.bithuman.ai/platforms/python/troubleshooting) | | CLI | [CLI](https://docs.bithuman.ai/platforms/cli/troubleshooting) | | LiveKit | [LiveKit plugin](https://docs.bithuman.ai/platforms/livekit/troubleshooting) | | Pipecat | [Pipecat service](https://docs.bithuman.ai/platforms/pipecat/troubleshooting) | | REST API | [REST](https://docs.bithuman.ai/platforms/rest#troubleshooting) · every error code: [Errors](https://docs.bithuman.ai/api/errors) | ## By task | Task | Its Troubleshooting table | |---|---| | Create an avatar | [Create an avatar](https://docs.bithuman.ai/build/create-avatar#troubleshooting) · creation errors: [Errors](https://docs.bithuman.ai/api/errors#agent-operations) | | A voice agent | [Voice agent](#voice-agent) | | A companion app | [Companion app](https://docs.bithuman.ai/build/companion-app#troubleshooting) | | A kiosk | [Kiosk](https://docs.bithuman.ai/build/kiosk#troubleshooting) | | A talking video | [Talking video](https://docs.bithuman.ai/build/talking-video#troubleshooting) | | Persona and gestures | [Persona](https://docs.bithuman.ai/build/persona#troubleshooting) · [Gestures](https://docs.bithuman.ai/build/gestures#troubleshooting) | | Claude, Cursor and other MCP clients | [MCP server](https://docs.bithuman.ai/build/mcp#troubleshooting) | ## Troubleshooting | Symptom | Cause | Fix | |---|---|---| | The first session on a new agent is slow | capacity is starting | wait: up to tens of seconds the first time; later sessions connect in seconds. If sessions keep failing, check [status.bithuman.ai](https://status.bithuman.ai) | | The agent will not launch right after creation | it is not `ready` yet, or its model is still being prepared for serving | poll until `ready`; retry the first session after a short wait | | `409 MODEL_NOT_GENERATED` | the session asked for a model the agent does not have | check `supported_models`; [add the model](https://docs.bithuman.ai/api/agents#add-a-model-to-an-existing-agent) | | The session ends at once with `avatar_error: "model_not_generated"` | a `?model=` in the URL named a model the agent does not have | remove `?model=`, or add the model | | `404` on `/speak` or `/add-context` | the agent has no live session | start a session first | | No microphone prompt in an embed | the iframe lacks `allow="microphone *"` | add it ([Web](https://docs.bithuman.ai/platforms/web)) | | In a room with several agents, the avatar stays silent for one | the avatar follows the agent that called `AvatarSession.start()` | start the avatar from the agent it should speak for | | Creation stays at `lip_sync` for a long time | that is the Expression 2 training step (it takes longer to build) | keep polling | Creation errors and their fixes are on [Errors](https://docs.bithuman.ai/api/errors#agent-operations). ### Plan and credit refusals Every SDK and the CLI refuse a render or session the same way, with the service's reason in the message (the CLI exits 77). Each code, its link field and the exact wording: [Errors](https://docs.bithuman.ai/api/errors#plan-and-credit-refusals). | The message says | Cause | Fix | |---|---|---| | *API and SDK access starts at the Creator plan* | since 2026-10-19, a Free account's API secret (`403 PLAN_REQUIRED`) | [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | *the API secret was rejected*, *was not accepted* or *account suspended* | a revoked or mistyped secret; since 2026-10-19, an older SDK or CLI also says this for a Free account | create a new one under [API secrets](https://www.bithuman.ai/developer/api-keys); if a new secret is refused too, [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | *Your … plan allows N cloud avatar sessions at once, and N are running (N/N)* | the plan's [concurrent cloud sessions](https://docs.bithuman.ai/api/rate-limits#session-concurrency) (`403 CONCURRENCY_LIMIT_REACHED`); every running session holds a slot until it ends | [terminate a session](https://docs.bithuman.ai/api/runtime-sessions#terminate-a-session) to free its slot at once, or [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | *as many agents as its plan allows*, or `403 AGENT_LIMIT_REACHED` | a new agent would pass the plan's agent limit; existing agents keep working | delete an agent, or [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | *no credits remaining* or *out of bitHuman credits* | no credits left (`402 INSUFFICIENT_BALANCE`) | [top up](https://www.bithuman.ai/billing#credits) on the Creator plan or higher | | *this account is suspended* | runtime access is suspended (`403 RUNTIME_SUSPENDED`) | [contact support](https://docs.bithuman.ai/support); a plan change does not clear it | ## Voice agent The [voice agent](https://docs.bithuman.ai/build/voice-agent), with the CLI or the Python example. | Symptom | Cause | Fix | |---|---|---| | `bithuman run` exits 69: `livekit-server 1.8.0 at …/livekit-server is too old for `bithuman run`` | The CLI needs livekit-server 1.13 or newer | `brew upgrade livekit` (macOS), or reinstall the CLI (Linux: its download includes one) | | The video stalls for 1–2 s every 15 s, or a LiveKit Meet tile goes black | `livekit-server` older than 1.9.12: the browser leaves and rejoins the room every 15 s | `brew upgrade livekit` (macOS) or `curl -sSL https://get.livekit.io \| bash` (Linux), then restart `livekit-server` | | `livekit-server not found` (exit 69) | LiveKit is not installed | `brew install livekit` (macOS) or `curl -sSL https://get.livekit.io \| bash` (Linux) | | The avatar never appears | No or invalid API secret | CLI: `bithuman login`. Python example: set `BITHUMAN_MASTER_SECRET` in `.env` | | The avatar never appears; the terminal shows `essence-2: ffmpeg not found` | Essence 2 unpacks its avatar with `ffmpeg` | `sudo apt install -y ffmpeg`, then run again | | The page says it could not connect | `livekit-server --dev` is not running | Start it, then click **Start** again | | Nothing happens after joining | `livekit-server --dev` or `agent.py` is not running | Start both, `livekit-server` first | | Another device on your network cannot join | `--dev` listens on `localhost` only | `livekit-server --dev --bind 0.0.0.0 --node-ip `; other browsers also need HTTPS for the microphone | | On a Mac, your own page with no microphone, on the same machine as the avatar, fails with `could not establish pc connection` | Chrome hides the machine's local addresses until the page has microphone permission | call `navigator.mediaDevices.getUserMedia({ audio: true })` before connecting, or open the page from another device | | `OSError: PortAudio library not found` | the system library is missing | `sudo apt install libportaudio2` (Debian, Ubuntu) | | `cv2.error: … The function is not implemented` | the headless OpenCV build won the install | `pip install --force-reinstall --no-deps opencv-python` | | `error: externally-managed-environment` | outside the virtualenv | `. .venv/bin/activate` | | No microphone input on macOS | the terminal has no microphone permission | System Settings → Privacy & Security → Microphone | ## Next - [Models](https://docs.bithuman.ai/models) · [Agents API](https://docs.bithuman.ai/api/agents) · [Errors](https://docs.bithuman.ai/api/errors) --- # Swift troubleshooting URL: https://docs.bithuman.ai/platforms/swift/troubleshooting > Fix Swift package errors on iPhone, iPad and Mac, by symptom. ## iOS | Symptom | Cause | Fix | |---|---|---| | `create` throws `meteringRefused` (C: `be_essence2_create` returns `-3`): *no API secret was found* | no secret | call `Essence2Credential.set` / `Expression2Credential.set`, or set `BITHUMAN_API_SECRET` in the scheme | | *the API secret was rejected* | revoked or mistyped secret; from 2026-10-19, a Free account | create a new one under [API secrets](https://www.bithuman.ai/developer/api-keys); on Free, [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | *cannot reach bitHuman to verify your credential* | no network at first contact | fix the network, then create again | | `create` throws `meteringRefused`, or `meteringRefusal` is set after `warmUp()`: *this account has no credits remaining (402)* | the account is out of credits | [top up](https://www.bithuman.ai/billing#credits), then start a new session; `warmUp()` does not throw, so check `meteringRefusal` after it | | `pull()` keeps returning `nil` right after `feed()` | frames arrive asynchronously, and Essence 2 hands out at most 25 a second | poll, or use `frames()` | | An Expression 2 reply fed in real time freezes, then skips ahead, about every 1.6 s | the engine renders 1.6 s of audio at a time; the reply started before the next chunk could arrive | update to Swift package 2.20.6 or newer, where `frames()` waits until the reply can play through. On older packages, feed audio as soon as you have it and start the voice 0.75 s after the reply's first frame | | crash in `__cxa_finalize` when the app quits | `Essence2Engine.quiesceAll()` (C: `be_essence2_quiesce_all`) was not called | call it from `applicationWillTerminate` | | `unable to resolve module dependency: 'Expression2'` on a Simulator build | the default destination also builds x86_64 | add `ARCHS=arm64`, or set `EXCLUDED_ARCHS[sdk=iphonesimulator*] = x86_64` in the target | | `expression is 'async' but is not marked with 'await'` on `player.scheduleBuffer(reply)` | Xcode 26 imports an `async` overload | call `player.scheduleBuffer(reply, completionHandler: nil)` | | `duplicate symbol` naming `MLX` at the final link, or Essence 2 memory rising in a long session | an older Swift package | raise `from:` to the version on [Downloads & versions](https://docs.bithuman.ai/downloads), then `swift package update` | | a link error naming `BithumanEngineProtocol` | that product was added beside `Expression2`, which already contains it | depend on `Expression2` only | | `401 MISSING_AUTH` downloading a model | the agent code and `model=` do not match a sample avatar | check the code, or send your API secret for your own agent | | `404` (*Agent not found for code*) downloading a model | the agent does not belong to the account of the API secret you sent, or it has no model of the kind you asked for (`model=expression-2` needs an Expression 2 agent, `model=essence-2` an Essence 2 agent) | use the secret of the account that owns the agent, and check the code and `model=` under [your agents](https://docs.bithuman.ai/api/agents) | ## macOS | Symptom | Cause | Fix | |---|---|---| | `refusing to serve: no API secret was found` | no secret in this shell or scheme | `export BITHUMAN_API_SECRET=…`, or set it in the scheme | | *cannot reach bitHuman to verify your credential* in a Mac app | App Sandbox blocks outgoing connections | tick **Outgoing Connections (Client)** under App Sandbox | | `create` throws before `engine ready` | the model files are missing | run `./setup.sh` from the example folder, so `Model/` holds the three files | | The first run is slow | the engine is prepared for this Mac once | keep `Model/staged/` between runs | --- # Android troubleshooting URL: https://docs.bithuman.ai/platforms/android/troubleshooting > Fix Android SDK errors from Gradle, the secret and the device. | Symptom | Cause | Fix | |---|---|---| | `Expression2Exception` from `create()` naming the API secret | no secret set | call `Expression2Credential.set(secret)` before `fetch()` and `create()` | | `Essence2MeteringRefused` (`ai.bithuman.elevate.MeteringRefused` in stack traces) on the first Essence 2 `pull()` | no secret set | call `Essence2Credential.set(secret)` before `fetch()` and `create()` | | A refusal reading *refusing to serve: API and SDK access starts at the Creator plan* | the account's plan does not include SDK access; from 2026-10-19 this includes Free accounts | [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | A refusal reading *this account is already running as many sessions as its plan allows* | every concurrent session of the plan is in use | `close()` the avatars you no longer show, or upgrade the plan | | A refusal reading *this account is suspended* | the account is suspended | contact support at team@bithuman.ai | | A refusal reading *this account has no credits remaining (402)* (Essence 2: `Essence2MeteringRefused`; Expression 2: `Expression2Exception`) | the account is out of credits | [top up](https://www.bithuman.ai/billing#credits); the next meter report is accepted | | `Essence2StoreException` from `fetch()` with `code` `OFFLINE` or `NETWORK_TRANSIENT` | no network, or bitHuman's server did not answer in time | call `fetch()` again later (`retriable` is true); the download keeps its bytes. It says nothing about the secret: do not sign the user out | | `Essence2StoreException` from `fetch()` with `code == OUTDATED` | the avatar was published again while it downloaded: the server now describes other files | call `fetch()` again (`retriable` is true); it follows the current files. Decide on `code` and `retriable`, never on the message | | *published before the renderer in this SDK* from `Essence2Bundle.open()`, or an `IllegalStateException` from Essence 2 `create()` naming the agent code | the avatar's files on the phone are older than the engine accepts, for example a folder staged by hand | `store.fetch(code, force = true)`, then open and create again | | `Essence2StoreException` from `fetch()` | no secret was set when the store downloaded | call `Essence2Credential.set(secret)` before `fetch()` | | Expression 2 renders slowly; `acceleratorNote` says no `libQnnTFLiteDelegate.so` | the accelerator runtime was excluded, or legacy packaging is off | keep the dependency whole and set `useLegacyPackaging = true` | | The first Expression 2 `create()` after install is slow | the accelerator prepares the decoder once and keeps it; later launches reuse it | create on a background thread at app start; only the first launch after install pays it (and again after an SDK or OS update) | | Download refused with `401` | the avatar is private | set its owner's API secret with `Expression2Credential.set` or `Essence2Credential.set` | | `409 MODEL_NOT_GENERATED` on download | the agent has no model of that kind yet | [add the model](https://docs.bithuman.ai/api/agents#add-a-model-to-an-existing-agent), then retry | | `Could not find ai.bithuman:expression2-android:…` (or `essence2-android`) | bitHuman's Maven repository is not in the build's repositories | add the `exclusiveContent` block for `https://maven.bithuman.ai` to `settings.gradle.kts`, as in [Install](https://docs.bithuman.ai/platforms/android#install) | | *SSL peer certificate or SSH remote key was not OK* with the deprecated first-generation SDK, `ai.bithuman:sdk` | an older version of that SDK | use `implementation("ai.bithuman:sdk:2.3.8")`; it comes from `maven.bithuman.ai` only, not Maven Central, so add the `exclusiveContent` block from [Install](https://docs.bithuman.ai/platforms/android#install). New projects use `essence2-android` or `expression2-android` | | Manifest merge fails on `minSdk` | `essence2-android` needs `minSdk 29` | raise the module to 29 | | `Unresolved reference: BuildConfig` | the Android Gradle Plugin turns `BuildConfig` off by default | add `buildFeatures { buildConfig = true }` | | `Unresolved reference 'MeteredDoorResolver'` | the resolver's public name is `Essence2MeteredDoorResolver` | you rarely need it: `Essence2Credential.set(secret)` covers downloads. To pass a secret explicitly: `import ai.bithuman.essence2.Essence2MeteredDoorResolver`, then `Essence2ModelStore(context, urlResolver = Essence2MeteredDoorResolver(secret))` | | Gradle stops with `What went wrong:` followed only by a Java version number (such as `25.0.4.1`) | Gradle 8.11 cannot run on that JDK | set `JAVA_HOME` to JDK 17 or 21 and build again | | The session is refused although you set a secret | `BuildConfig.BITHUMAN_API_SECRET` is empty | set `bithuman.apiSecret` in `local.properties` or `BITHUMAN_API_SECRET`, then rebuild | | `UnsatisfiedLinkError` on an emulator | the engines are `arm64-v8a` only | run on a physical arm64 handset | --- # Flutter errors URL: https://docs.bithuman.ai/platforms/flutter/errors > What BithumanAvatar.load throws, why a voice session ends, and what to do. A failure reaches your app in one of two places: `BithumanAvatar.load` throws, or a running voice session ends once on `errorStream`. Decide on the code, never on the message, which is written for people and can change. A network error never means the API secret is wrong. Retry it later, and do not sign the user out or ask for a new secret. ## Loading an avatar `load` throws `BithumanModelRejected` when the engine refuses the avatar file, `BithumanEntitlementException` when bitHuman has not said yes to this API secret for this avatar (plugin 2.6.36 or newer), and a `PlatformException` for everything else. The installers (`downloadAgentImx`, `downloadExpression2Avatar`, `downloadExpression2Agent`, `downloadEssence2Bundle`) throw `BithumanEntitlementException` too. Neither class is a `PlatformException`, so catch each one: ```dart try { final avatar = await BithumanAvatar.load(code, engine: 'essence2', apiSecret: secret); } on BithumanModelRejected catch (e) { // MODEL_REJECTED: this avatar cannot run here; show it as unavailable } on BithumanModelPreparing catch (e) { // still being prepared for this device (2.6.40): show e.userMessage, load again on BithumanModelPreparing.retryDelay } on BithumanEntitlementException catch (e) { // e.refused true: bitHuman said no to this secret for this avatar; do not retry with it // e.refused false: bitHuman could not be asked (offline, a timeout); retry when online } on PlatformException catch (e) { // e.code: load_failed, load_cancelled, unsupported, detached, BAD_ARGS } ``` | Code | Platforms | What happened | Retry helps | What to do | |---|---|---|---|---| | `MODEL_REJECTED` (`BithumanModelRejected`) | Android, iOS, macOS | The engine refused the avatar file. `nativeCode` -4 on Essence 2: the file was published before the engine's current version. On Android the plugin downloads the file again once before it gives up. | No | Show the character as unavailable. On iOS and macOS, download the file again (`GET /v1/agent/{code}/model/download`). | | `BithumanModelPreparing` (Android code `model_preparing`) | Android, iOS, macOS | The character is still being prepared for this device: it is still training, or its on-device copy is still being built (the door answered 404 `MODEL_ARTIFACT_NOT_READY`). Plugin 2.6.40 and newer; earlier versions report it as `BithumanEntitlementException`, `refused: false`. Nothing is downloaded or opened. | Yes, later | Show `userMessage` ("Preparing this character for your device…") and load again on `BithumanModelPreparing.retryDelay` (30 s, 60 s, 120 s, then every 5 minutes), or use `retryWhileModelPreparing`. Never ask for a new API secret. | | `BithumanEntitlementException`, `refused: true` | Android, iOS, macOS | bitHuman refused this API secret for this avatar: it is another account's private avatar, or the secret is revoked. A copy kept on the device is not opened. | No | Pass the API secret of the account that owns the avatar. | | `BithumanEntitlementException`, `refused: false` | Android, iOS, macOS | bitHuman could not be asked (offline, a timeout, a 5xx), and this secret has no recent yes for the kept copy: within 24 hours for an account's own avatar, 7 days for a public one. On Android the first open of each kept avatar after updating to 2.6.36 asks once. | Yes, once online | Call `load` again when the device is online. | | `load_failed` | Android | The download or the engine failed; the message names the cause: no network, a missing or refused API secret, another account's private avatar. | Only when the cause is the network; the download keeps its bytes | Fix the cause. For the network, wait for it and call `load` again. | | `load_cancelled` | Android | `BithumanAvatar.cancelLoad(code)` or `BithumanAvatar.clearCredentials()` stopped the load. | — | Nothing: the next `load` of that code continues the download. | | `unsupported` | Android, iOS, macOS | `engine:` names no engine, or the agent code is empty. On iOS and macOS also: Expression 2 below iOS 18 or macOS 15 (plugin 2.6.39 and newer), Essence 2 below iOS 26 or macOS 26 (the message names the version it needs), or `'essence2'` in a build that does not carry the Essence 2 engine. | No | Pass `engine: 'expression2'` or `'essence2'`, and the agent code. Check the OS version before you download a model's files: Expression 2 needs iOS 18 or macOS 15, Essence 2 iOS 26 or macOS 26. | | `detached` | Android | The Flutter engine went away while the avatar loaded. | No | Load again from the new engine. | | `BAD_ARGS` | iOS, macOS | `load` was called without a path. | No | Pass the avatar's file (Essence 2) or folder (Expression 2). | On iOS and macOS a missing or refused API secret for a file your app downloaded itself does not throw: the avatar never becomes ready (`isReady` stays false). Wait on `avatar.ready` with a timeout, and check the secret when it expires. Always pass `engine:`. ## Voice session A `BithumanRealtimeSession` reports a failure that a retry cannot fix once, as a `RealtimeSessionError` on `errorStream` (also kept in `lastError`), then `RealtimeStatus.error`. The session then stops whole: microphone and speaker off, captions ended, streams closed. It does not reconnect; fix the cause and build a new session. | `code` | What happened | What to do | |---|---|---| | `UNAUTHORIZED` | The relay refused the API secret at the start (HTTP 401): missing, revoked or mistyped. | Use a valid [API secret](https://docs.bithuman.ai/start/api-secret). | | `INSUFFICIENT_BALANCE` | The account has no credits, at the start (HTTP 402) or when they run out during the session. | [Top up](https://www.bithuman.ai/billing#credits), then start a new session. | | `PAYWALL` | The account has no credits left for a voice session: its plan's credits and its top-ups are spent (HTTP 402). bitHuman returns it for bitHuman Live sign-ins; a session on your own API secret ends with `INSUFFICIENT_BALANCE` instead. | Choose a plan or top up, then start a new session. | | `FORBIDDEN` | The relay refused the start (HTTP 403), or bitHuman stopped the session. At the start the usual cause is the model: `gpt-realtime` (the session's default before plugin 2.6.36) needs an entitlement. | Pass `model: 'gpt-realtime-mini'`. Otherwise check the plan and the secret. | | `PLAN_REQUIRED` | The account's plan does not include the session. At the start the relay answers HTTP 403, which arrives as `FORBIDDEN`. | [Choose a plan](https://www.bithuman.ai/pricing). | | `SESSION_DURATION_LIMIT` | The session reached its maximum length, one hour. | Start a new session. | | `MODEL_LOCKED` | A `session.update` tried to change the model fixed when the session connected. | Keep the model; open a new session for another. | | `BAD_REQUEST` | The relay refused the start (HTTP 400), for example a model name it does not serve. | Use `gpt-realtime-mini`. | | `MODEL_REJECTED` | The avatar's engine refused its model file during the session. | As for `load`, above. | A dropped connection is not on `errorStream`: the session reconnects, waiting 1 s and doubling up to 30 s (8 attempts), and reports `RealtimeStatus.error` only when they run out. A relay at capacity (HTTP 503) reports `RealtimeStatus.error` too; start again shortly. The relay's codes and limits are on [Realtime relay](https://docs.bithuman.ai/api/realtime#limits--billing). ## Android engine refusals On Android the plugin runs the [Android SDK](https://docs.bithuman.ai/platforms/android)'s engines. A refusal of the account (the plan, too many sessions, a suspended account, no credits) or an out-of-date avatar file is described, with its fix, in [Android troubleshooting](https://docs.bithuman.ai/platforms/android/troubleshooting). --- # Flutter troubleshooting URL: https://docs.bithuman.ai/platforms/flutter/troubleshooting > Fix Flutter plugin build and runtime errors by symptom. | Symptom | Cause | Fix | |---|---|---| | `UnsatisfiedLinkError` on an emulator | the engines are `arm64-v8a` only | run on a physical arm64 phone | | `flutter pub get` fails: *version solving failed*, naming `bithuman` and an SDK version | the plugin needs Dart 3.11.5 or newer | upgrade Flutter to a release that ships Dart 3.11.5 or newer | | The app shows a refusal and asks for a secret | no API secret, or a rejected one | enter a valid [API secret](https://docs.bithuman.ai/start/api-secret), or build with `--dart-define=BITHUMAN_API_SECRET=…` | | Manifest merge fails on `minSdk` | the plugin needs `minSdk 29`, whichever model you use | set `minSdk = 29` in `android/app/build.gradle.kts` ([Install](https://docs.bithuman.ai/platforms/flutter#install)) | | Expression 2 runs slowly on Android, or a library is reported missing | the engines' native libraries were compressed into the APK | set `packaging { jniLibs { useLegacyPackaging = true } }` ([Install](https://docs.bithuman.ai/platforms/flutter#install)) | | `MissingPluginException` from `pushAudio` on Android | a plugin older than 2.6.36: Android had no `pushAudio` | update to 2.6.36, or send 24 kHz speech with `playSpeakerPCM` ([Integrate into your app](https://docs.bithuman.ai/platforms/flutter/app#integrate-into-your-app)) | | On iOS or macOS the lips move but nothing is heard | `pushAudio` drives the lips only | call `audioStart(enableMic: false)`, then `playSpeakerPCM` | | `PlatformException(unsupported)` from `load` | `engine:` names no engine; on iOS or macOS also Expression 2 below iOS 18 or macOS 15 (plugin 2.6.39), or Essence 2 below iOS 26 or macOS 26 | pass `engine: 'expression2'` or `engine: 'essence2'`; raise the app's deployment targets to the model's minimum (Expression 2: iOS 18.0, macOS 15.0) | | `load` or an installer throws `BithumanEntitlementException` | bitHuman refused this API secret for this avatar (`refused: true`), or could not be asked while the device holds no recent yes for it (`refused: false`) | pass the owning account's API secret; for `refused: false`, retry online ([Flutter errors](https://docs.bithuman.ai/platforms/flutter/errors#loading-an-avatar)) | | After a sign-out, the next account can still load the previous account's avatars | the app kept the previous secret, or never cleared it | call `BithumanAvatar.clearCredentials()` at sign-out, and pass each account's own `apiSecret` | | On iOS or macOS the avatar never becomes ready | no API secret, or a refused one: the Apple engines do not throw for it | pass a valid `apiSecret:` to `load` | | `load` throws `BithumanModelRejected` (`MODEL_REJECTED`) | the engine refused the avatar file | see [Flutter errors](https://docs.bithuman.ai/platforms/flutter/errors#loading-an-avatar) | | A voice session ends with `FORBIDDEN` as it starts | the model needs an entitlement: `gpt-realtime` does (the session's default before plugin 2.6.36) | pass `model: 'gpt-realtime-mini'`, the default in plugin 2.6.36 and newer | | A voice session ends with `PAYWALL`, `INSUFFICIENT_BALANCE` or `PLAN_REQUIRED` | no minutes, no credits, or the plan does not include it | see [Flutter errors](https://docs.bithuman.ai/platforms/flutter/errors#voice-session) | | `pod install` fails on iOS or macOS | the deployment target is below the plugin's floor: iOS 16.4 and macOS 14.0 from plugin 2.6.37 (2.6.36: iOS 16.0, macOS 26.0) | raise the Podfile platform and the Runner targets: `platform :ios, '16.4'` and `IPHONEOS_DEPLOYMENT_TARGET = 16.4`; `platform :osx, '14.0'` and `MACOSX_DEPLOYMENT_TARGET = 14.0` | | The avatar shows no new frames after the app was in the background | after 60 seconds in the background (or with no frame taken) the session ends, billed to that point (plugin 2.6.37) | nothing to do: frames come back, in a new session, when the app is on screen again | | The iOS or macOS build fails, naming the engines' floor, after updating the plugin | `Podfile.lock` already resolves the pod and the app is below the floor (2.6.37: iOS 16.4, macOS 14.0) | raise the targets to the floor, keep `$(inherited)` in `GCC_PREPROCESSOR_DEFINITIONS`, then run `pod install` | | The iOS or macOS build cannot find the engines | the bootstrap step was skipped | run `scripts/bootstrap.sh` in the plugin's folder, then build again | | A macOS link error names `onnxruntime` | the plugin's ONNX Runtime was not staged, the plugin is older than 2.6.39 (those link Homebrew's), or another ONNX Runtime is linked into the app (a duplicate-symbol error) | update to plugin 2.6.39 or newer, run `scripts/bootstrap.sh` in the plugin's folder, then `pod install`; remove any other ONNX Runtime (the `onnxruntime-objc` or `onnxruntime-c` pods, or your own `libonnxruntime`) | --- # Web troubleshooting URL: https://docs.bithuman.ai/platforms/web/troubleshooting > Fix embed and in-tab rendering problems by symptom. | Symptom | Cause | Fix | |---|---|---| | The microphone never activates | `allow` is missing `microphone *` | use `allow="microphone *"` | | The frame shows `Agent not found` | the agent code is wrong | copy the code from the agent's Share Agent dialog | | With `render=local`, the frame says "This device can't keep up with this avatar (reason). Try another device or browser." | unsupported browser, no supported graphics path, or the device measured too slow | choose `render=cloud` for that visitor; see [the device check](https://docs.bithuman.ai/platforms/web/webgpu) | | With `render=local`, the frame says "This avatar can only be rendered in the cloud" | an Expression 1 model | remove `render=local`, or add `model=` with another model the agent supports | | With `render=local`, the frame says "This avatar can't be rendered in the browser" | the avatar has no browser build | remove `render=local` | | With `render=local`, the frame says "In-browser rendering is turned off right now" | bitHuman has switched off in-tab rendering for this model | remove `render=local` | | The iframe shows a browser error page | your page sends `Cross-Origin-Embedder-Policy` | remove that header from the page that holds the iframe | | A blank frame | a service problem | check [status.bithuman.ai](https://status.bithuman.ai), then reload | | Your own avatar shows `Embedding is disabled for this agent` | its **Let anyone talk without signing in** setting is off | turn it back on in the agent's Share Agent dialog, or keep it off and pass an [embed token](https://docs.bithuman.ai/api/embedding) (`?token=`) | --- # Python troubleshooting URL: https://docs.bithuman.ai/platforms/python/troubleshooting > Fix Python install, secret and rendering errors by symptom. | Symptom | Cause | Fix | |---|---|---| | `error: externally-managed-environment` | `pip` targeted the system Python | create and activate a venv | | `ModuleNotFoundError: No module named 'bithuman'` | the venv is not active in this terminal | `source .venv/bin/activate` | | `pip` finds no wheel | Intel Mac, Windows on Arm, musl, or Python outside 3.10–3.14 | use a supported platform ([Windows](https://docs.bithuman.ai/platforms/windows) needs 64-bit Python on x86_64) | | `NotSupported` opening an Expression 2 file | the extra is missing | `pip install "bithuman[expression-2]"` | | `NotAuthorised`: *no credential was supplied* (first frame) or *no API secret was found* (`open`) | no secret in this shell | `export BITHUMAN_API_SECRET=…`; nothing is rendered or written | | `This render is metered and no API secret was found` from `python -m bithuman pull` | `pull` with an agent code needs the secret, a sample's code included | `export BITHUMAN_API_SECRET=…` (`.env` is deprecated), or pull a sample by name: `python -m bithuman pull wise-pup` | | `NotAuthorised` at `open`: *that API secret was not accepted* | the secret was rejected; from 2026-10-19, a Free account | create a new one under [API secrets](https://www.bithuman.ai/developer/api-keys); on Free, [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | An MP4 with sound and no picture | a refused render through the deprecated `render_offline` leaves the audio track | render with `bithuman.open(path).render(audio, out_mp4=...)`, which refuses before it writes anything; check the frame count it returns | | Frames look blue | frames are RGB and your display wants BGR | `image[:, :, ::-1]` | | Raw audio plays slow and long | decoded audio must be 16 kHz mono | pass a file path, or resample to 16 kHz | | `404 NOT_FOUND` downloading a model | not your agent and not a sample avatar | check the code under [your agents](https://docs.bithuman.ai/api/agents) | | The example window never opens (`GUI: NONE`) | the headless OpenCV build won the install | `pip install --force-reinstall --no-deps opencv-python` | --- # CLI troubleshooting URL: https://docs.bithuman.ai/platforms/cli/troubleshooting > Fix CLI install, sign-in and render errors by symptom. | Symptom | Cause | Fix | |---|---|---| | `bithuman: command not found` | `~/.local/bin` is not on `PATH` | `export PATH="$HOME/.local/bin:$PATH"` | | `bithuman: command not found` right after `curl -fsSL https://install.bithuman.ai \| sh` printed nothing | a network error stopped the download, so nothing was installed | run the install command again | | `Refusing to load formula … from untrusted tap` | Homebrew 7 needs the formula's full name | `brew install bithuman/bithuman/bithuman-cli` (`upgrade` works the same way) | | `not signed in`, exit 77, nothing written | no credential | `bithuman login`, or set `BITHUMAN_API_SECRET` | | `your credential is invalid or expired` or `the API secret was rejected`, exit 77 | the secret was revoked or mistyped; from 2026-10-19, a Free account | `bithuman login` again, or create a new API secret; on Free, [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | `bithuman login` prints `token exchange failed` or times out, exit 1 | the browser or device approval did not complete | run `bithuman login` (or `--device`) again | | `render` exits 69: `ffmpeg not found` | `ffmpeg` is not on `PATH` (common in scripts) | install it, or set `BITHUMAN_FFMPEG` to its path | | `run` with an Essence 2 avatar: no avatar in the page, and the terminal shows `essence-2: ffmpeg not found` | `ffmpeg` is not on `PATH` | `sudo apt install -y ffmpeg`, or set `BITHUMAN_FFMPEG` | | `run` says the `livekit-server` binary was not found | `livekit-server` is not installed | `brew install livekit` (macOS), or rerun the installer (Linux) | | `run` exits 69: `livekit-server 1.8.0 at …/livekit-server is too old for `bithuman run` (it needs 1.13 or newer)` | an old `livekit-server` found on `PATH` | `brew upgrade livekit` (macOS), or reinstall with `curl -fsSL https://install.bithuman.ai \| sh` (Linux) | | `SLUG_NOT_FOUND`, exit 66 | the slug is not in the sample list | `bithuman list` and copy a slug | | `pull ` fails with `404 NOT_FOUND` | not your agent and not a sample avatar | check the code under [your agents](https://docs.bithuman.ai/api/agents) | | `pull ` fails with `409 MODEL_NOT_GENERATED` | the agent has no model of that kind | [add the model](https://docs.bithuman.ai/api/agents#add-a-model-to-an-existing-agent), or pass the `--model` it has | | `PUBLIC_BIND_REFUSED`, exit 2 | `--host 0.0.0.0` without consent | use a LAN address, or set `BITHUMAN_ALLOW_PUBLIC_BIND=1` | | the installer says `could not reach …` or `could not determine the latest CLI release` | no connection to downloads.bithuman.ai: offline, a proxy or DNS | check the connection, then run the installer again | | the installer says `the download server is rate-limiting downloads from this network` | too many downloads from your network in a short time | wait a few minutes, then run it again | | the installer says `sha256 mismatch!` and stops | the download was cut short or changed on the way; nothing was installed | run the installer again | | `bithuman doctor` exits 1 on a fresh install: `Agent worker ✗ not found` | the first `bithuman run` sets up the worker | run `bithuman run` once | | many `Removing initializer` warnings and short bracketed diagnostic lines during an Essence 2 render | runtime diagnostics | expected | | the installer names your platform and stops | no binary for this platform | see Platform notes | --- # LiveKit troubleshooting URL: https://docs.bithuman.ai/platforms/livekit/troubleshooting > Fix LiveKit plugin launch and room errors by symptom. | Symptom | Cause | Fix | |---|---|---| | The mint call returns `403` | the token was minted for another agent, room or LiveKit URL | mint with the same `agent_code`, `room_name` and `livekit_url` the plugin uses | | The mint call returns `401` | a missing or invalid API secret | check `BITHUMAN_MASTER_SECRET` against your [API secret](https://docs.bithuman.ai/start/api-secret) | | The avatar speaks with the wrong model | the plugin serves the agent's own model | create an agent with the model you want | | The video stalls for 1–2 s every 15 s, or a LiveKit Meet tile goes black | `livekit-server` older than 1.9.12: the browser leaves and rejoins the room every 15 s | `brew upgrade livekit` (macOS) or `curl -sSL https://get.livekit.io \| bash` (Linux), then restart `livekit-server` | | Two voices play | the agent session also publishes audio | set `room_options=RoomOptions(audio_output=False)` | --- # Pipecat troubleshooting URL: https://docs.bithuman.ai/platforms/pipecat/troubleshooting > Fix Pipecat avatar start, video and session errors by symptom. | Symptom | Cause | Fix | |---|---|---| | `ValueError: BitHumanVideoService needs an avatar model` | no `model_path=` and no `BITHUMAN_MODEL_PATH` | pass `model_path="avatar.imx"` or `export BITHUMAN_MODEL_PATH=…` | | `ErrorFrame`: *the bitHuman avatar could not start: ImportError: The bitHuman Python SDK is not installed* | `bithuman` is missing from this environment | activate the venv, then `pip install "pipecat-bithuman[expression-2]"` (or `[essence-2]` for an Essence 2 file) | | `ErrorFrame`: *could not start: … api_secret is required* | no secret in the bot's environment | `export BITHUMAN_API_SECRET=…`, or pass `api_secret=` | | `ErrorFrame`: *could not start: … that API secret was not accepted* | the secret was revoked or mistyped | create a new one under [API secrets](https://www.bithuman.ai/developer/api-keys) | | `ErrorFrame`: *could not start: … API and SDK access starts at the Creator plan* | from 2026-10-19, a Free account | [choose a plan](https://www.bithuman.ai/pricing?from=docs) | | `ErrorFrame`: *could not start: … this avatar needs one more package* with an Expression 2 file | the `expression-2` extra is missing | `pip install "pipecat-bithuman[expression-2]"` | | `ErrorFrame`: *could not start: … this avatar needs one more package* with an Essence 2 file | the `essence-2` extra is missing | `pip install "pipecat-bithuman[essence-2]"` | | The bot speaks but shows no video, after an `ErrorFrame` | the avatar failed, and TTS audio passes through by default | fix what the `ErrorFrame` names; `audio_passthrough_on_error=False` drops the voice too | | No video and no `ErrorFrame` | video out is off in the transport | set `video_out_enabled=True` in the transport's params | | The picture is resized or stretched | the transport's video size differs from the avatar's | set `video_out_width` and `video_out_height` to the size the service logs on the first frame | | Log: *queued speech did not finish in … s; closing* | at `EndFrame` the service waits for the queued speech plus `stop_frame_timeout_s` and 1 s, at most `end_drain_timeout_s` (30 s by default), then closes the avatar | if the logged wait equals `end_drain_timeout_s`, raise it | | Session time keeps running after the user leaves | the pipeline still runs, so the avatar stays open | cancel the pipeline when the participant leaves (`await worker.cancel()`), or end it with `EndFrame` | | `404 NOT_FOUND` downloading a model | not your agent and not a sample avatar | check the code under [your agents](https://docs.bithuman.ai/api/agents) | Errors from the Python SDK itself: [Python troubleshooting](https://docs.bithuman.ai/platforms/python/troubleshooting).