Beatra troubleshooting: sign-in, credits, timeouts, errors
Fix the six common Beatra problems: sign-in, credits, slow or timed-out tasks, rejected parameters, version mismatch, and missing tasks, files, or voices.
Every Beatra failure carries an error code and a retryable flag: in a REST error body, in a failed MCP tool result, and in a failed task. Find the symptom below and work through its steps in order. Each section ends with the error codes that belong to it and what to do about each one. The error envelope and the retry rules are on Errors & retries.
Sign-in fails
Agents sign in to Beatra once, in the browser: the Beatra Skill requests a device code, opens an approval page, and waits while you approve. Its sign-in helper, scripts/authorize.py in the installed Skill folder, prints Beatra is ready when the connection works.
- The helper printed
BEATRA_AUTH_PENDING. The approval is still open. Open the approval link it printed, sign in, and choose Allow, then let the agent run the same command again. Every run continues the same approval, so you approve only once. An approval page stays open for up to an hour. - The helper printed
access_deniedorexpired_token. The approval was declined, or the page expired before Allow was chosen. Ask the agent to runpython3 scripts/authorize.pyagain for a new approval page. - Beatra worked before and now reports
BEATRA_AUTH_REQUIRED. The sign-in on this computer has ended: it was unused for 15 days, or the computer was disconnected under Devices in the console. Ask the agent to runpython3 scripts/authorize.pyagain and approve once. - A tool call returns
insufficient_scope. The connection lacks access a tool needs, andmissing_scopesnames it. Reconnect withpython3 scripts/authorize.py --forceand approve once. Retrying without reconnecting returns the same error. - The sign-in page will not load, or a verification code never arrives. Sign-in troubleshooting covers the WeChat QR code, email and phone codes, and signing in to the wrong account.
- Your own app gets
401. SendAuthorization: Bearer <API key>with a key from the console (Developer → API keys), on the API host that matches the key's region. See Authentication & request conventions.
| code | HTTP | retryable | description |
|---|---|---|---|
unauthorized | 401 | no | Missing or malformed authentication credentials. Send Authorization: Bearer <API key>. |
invalid_api_key | 401 | no | API key is invalid, disabled, revoked, or unknown. Create or rotate keys in the console (Developer → API keys) and retry with the new key. |
api_key_region_mismatch | 400 | no | API key region prefix does not match this endpoint. Call the API host matching the key's region, or use a key issued for this region. |
tenant_disabled | 403 | no | Tenant has been suspended or disabled. Contact support; retrying cannot succeed. |
forbidden | 403 | no | Caller does not have permission for this operation. Use a credential with the required permission; retrying unchanged cannot succeed. |
email_send_failed | 502 | yes | Login-code email could not be delivered (transient send failure). Request a new code after a brief backoff. |
Not enough credits
Paid tools check the balance before they start. When it is short, the call returns insufficient_balance (HTTP 402): the work did not start and nothing was charged.
- Top up in the console at console.beatra.ai/wallet. Credits take effect immediately. The wallet's "Adding credits to: …" line names the account that receives them.
- Retry the same request unchanged: the same arguments and the same
client_request_idorIdempotency-Key. No reinstall or new sign-in is needed. - In an agent, tell it you have topped up. After a refusal, the Beatra Skill answers further calls to the same tool on this computer with the same message (
details.local_hold) until you say you have topped up, so a long batch stops at the first refusal. The hold also lifts by itself after 30 minutes. - The top-up went through but the balance has not moved. The credits most likely went to another account. Open the top-up link from the agent again and check "Adding credits to: …", or merge the two accounts: see Accounts and merging.
- The balance is negative after a task. A task's measured usage can exceed its estimate. The result stays valid; new paid work waits for a top-up.
Prices per model are live in beatra.models.list and GET /v1/catalog/models; plans and top-up packs are on the pricing page. How charging and refunds work: Billing & usage.
| code | HTTP | retryable | description |
|---|---|---|---|
insufficient_balance | 402 | no | Insufficient credits: this request was not started and nothing was charged. Add credits at https://console.beatra.ai/wallet?intent=buy — they take effect immediately; then retry this same request. No reinstall or re-authorization is needed. |
billing_failed | 500 | yes | Charge or refund attempt failed after retries. Retry with the same Idempotency-Key / client_request_id; the identity guarantees no double charge. |
payment_provider_unavailable | 503 | no | Payment checkout provider is not configured for this payment method. Choose another payment method in the console. |
voice_activation_required | 422 | no | This voice is a free preview and can't be used for speech until it is activated. Confirm the activation price with the user, then call beatra.voices.activate. |
price_confirmation_required | 422 | no | The activation quote has expired or changed. Show the new quote to the user, get their consent, then call beatra.voices.activate again with the new confirmation_token and confirm_credits. |
Slow tasks and timeouts
Generation runs as an asynchronous task: queued, then running, then succeeded, failed, or canceled. A task that is still queued or running is working, and the result arrives when it reaches a final state.
- The task is still
queuedorrunning. Keep checking the same task withbeatra.tasks.getorGET /v1/tasks/{task_id}, about every 5 seconds. Submitting the request again creates a second task that is billed separately. progress.stageisfinalizing. The model has finished and Beatra is storing the files. Beatra keeps trying to fetch them for up to about 40 minutes without generating or charging again. If they still cannot be fetched, the task fails withmodel_output_invalidand its credits are refunded.- The call timed out or the connection dropped. Retry with the same
client_request_id(MCP) orIdempotency-Key(REST) and exactly the same arguments: Beatra returns the original task instead of starting a new one. If the task ID was lost, list recent tasks withbeatra.tasks.listorGET /v1/tasksfirst. - The error has
retryable: true. Wait for theRetry-Afterinterval when there is one, then retry the same request.429responses carryX-RateLimit-*headers; see Rate limits. - Your plan's creations in progress are all in use. A new request does not start and nothing is charged. Wait for one to finish and retry the same request; see How many at a time.
model_unavailable. Pick another model frombeatra.models.list, or usemodel: "auto"so Beatra picks one that is available.- Cancel returned
409. Execution has started and continues. Keep checking the same task until it reaches a final state.
| code | HTTP | retryable | description |
|---|---|---|---|
model_timeout | 504 | yes | The model request timed out. Retry with backoff. |
model_request_failed | 502 | yes | The model request failed after retryable service errors. Retry with backoff; if it persists, adjust inputs or choose another model. |
model_unavailable | 503 | yes | The requested model is not currently available. Retry with backoff, switch to another selectable model (beatra.models.list or GET /v1/catalog/models), or use model=auto. When present, details.reason and details.available_at give the cause and the expected recovery time. |
model_rate_limited | 429 | yes | Model capacity was rate-limited. Retry after a backoff. |
rate_limited | 429 | yes | Caller-side rate limit exceeded. Retry after the Retry-After interval; X-RateLimit-* headers report the active budget. |
voice_activation_daily_limit | 429 | no | This account has activated 3 voices today, the daily limit. Nothing was charged. To activate more voices today, contact Beatra support; the limit resets at 00:00 UTC (08:00 Beijing time). |
request_in_progress | 409 | yes | Same idempotency identity matches an in-flight request. Retry later with the same identity; the original response will be returned. |
conflict | 409 | no | The operation conflicts with the resource's current state — for task cancellation this means execution continues. Follow details.action (usually: keep polling the same task); do not resubmit the work. |
upload_stalled | 408 | yes | An upload stopped sending data for too long, or ran past the upload time limit. Send the same PUT to the same upload URL again; if the upload grant has expired, request a new one with beatra.assets.upload. |
model_output_invalid | 502 | yes | The model returned a result that cannot be delivered, such as missing or corrupt audio, or a generated file that could not be retrieved. The task fails and its charge is refunded; submit a new request. |
internal_error | 500 | yes | Unclassified server-side error. Retry with the same idempotency identity; if it persists, report the request_id. |
Invalid parameters
A rejected request names the field: error.param is a JSON Pointer to it, and details.errors (validation) or details.candidate_failures[] (model options) say what each field accepts.
- Change the named field and send the corrected request with a new
client_request_id. The inputs changed, so it is new work; reusing the old identity returnsidempotency_conflict. - Check the model's current limits (resolution, duration, aspect ratio, input types) in
beatra.models.listorGET /v1/catalog/models, or usemodel: "auto"so Beatra picks a model that supports the whole request. A model you name explicitly is never replaced. - Media inputs: pass an HTTPS URL Beatra can reach, or upload the file with
beatra.assets.uploadand pass the artifact ID it returns. See Upload source media. - Content review:
safety_rejectedandcontent_filteredmean the prompt or an input needs to change. The same content is rejected again. - Argument lists: every MCP tool's arguments are in the MCP tool reference, and every REST body in the API reference.
| code | HTTP | retryable | description |
|---|---|---|---|
invalid_request | 422 | no | Request body fails structural validation. param points to the first offending field; details.errors lists every failure with its loc and reason. Fix the named fields and resend. |
unsupported_capability | 400 | no | Capability does not exist or is disabled. GET /v1/catalog/capabilities lists the currently available capabilities. |
unsupported_model | 400 | no | Model does not exist or is not selectable for this capability. Discover selectable models with beatra.models.list or GET /v1/catalog/models, or use model=auto. |
unsupported_option | 422 | no | The selected concrete model does not support a requested value or control. param identifies the field and details.candidate_failures[] carries a specific failure code such as unsupported_resolution, unsupported_duration, or unsupported_aspect_ratio, plus the received and supported values. Change the named field or choose a different model; with model=auto this is returned only when no candidate can satisfy the request. |
no_eligible_model | 422 | no | No live model can honor the complete model=auto request. details.candidate_failures[] lists each provider-neutral rejection; change only the incompatible fields or pick a listed concrete model. |
voice_model_incompatible | 422 | no | The requested voice does not resolve on the requested model. Use model=auto, a compatible model, or another voice from the voices list. |
unsupported_input_modality | 422 | no | The selected model does not support an input modality in the request (such as image, audio, or file input). param points to the first offending field; remove it or choose a model that supports it. |
context_length_exceeded | 422 | no | The request exceeds the selected model's context window. Shorten the input or choose a model with a larger context window. |
invalid_media | 422 | no | Media input is malformed or cannot be decoded. Re-export or re-encode the file and submit it again; param names the offending field. |
unsupported_media_type | 422 | no | Media input type is not supported for this capability. Convert to a supported format (see the capability page or model constraints) and resend. |
media_too_large | 413 | no | Media input exceeds the allowed size. Compress or trim the input, or upload it first and pass an artifact reference. |
media_fetch_failed | 422 | yes | Beatra could not access an input resource. Check that the resource is reachable over HTTPS, or upload it and pass an artifact reference. |
safety_rejected | 400 | no | The request did not pass content safety review. Ask the user to review the prompt and every input resource, then edit or replace content that may be unsafe before submitting a new task with a new client_request_id. Retrying the same content will not help. |
content_filtered | 502 | no | A safety filter blocked the output mid-generation. Rephrase the prompt or switch models; an identical retry is usually blocked again. |
idempotency_conflict | 409 | no | Same Idempotency-Key / client_request_id was used with a different request body. Submit changed work with a NEW identity; to retry identical work unchanged, reuse the original. Inspect the existing task before choosing. |
callback_url_required | 422 | no | A callback URL is required when a callback signing key is selected. Add callback_url or remove callback_signing_key_id. |
callback_signing_key_not_found | 404 | no | Callback signing key does not exist or is not visible to this account. List signing keys in the console and pass a current key id. |
callback_signing_key_inactive | 422 | no | Callback signing key is retired and cannot be selected for a new task. Select an active key, or omit the key id for unsigned delivery. |
invalid_window | 422 | no | Time range is invalid. |
invalid_cursor | 400 | no | Pagination cursor is malformed. |
Version mismatch
The Beatra Skill on your computer stays at the version you installed until you update it. At most once a day it checks the store or tool you installed it from, and when a newer version is there it prints one line with the command that updates it.
-
Check by hand from the installed Skill folder with
python3 scripts/mcp_client.py update --check. It reports what your store offers and installs nothing. -
Update through the place you installed from, then start a new agent session so the agent loads the new version:
Installed with Update with The Beatra install message Send the install message again skills CLI npx skills update <package> -g -yfor a global install, ornpx skills update <package> -p -yin the project folderGitHub CLI gh skill update <package>ClawHub CLI clawhub update <package> --workdir <dir> --dir <skills-dir>SkillHub CLI skillhub install <package> --force --dir <skills-dir>WorkBuddy Update the Skill in WorkBuddy -
Public social data says
schema_hash does not match the current tool. The tool's arguments changed after the agent read them. Callbeatra.social.tools.getagain and submit with the newschema_hashand a newclient_request_id. -
An older integration calls a path or option the API no longer serves. Compare the call with the API reference and the MCP tool reference.
| code | HTTP | retryable | description |
|---|---|---|---|
skill_package_format_invalid | 422 | no | Skill package identity is malformed. Use a lowercase hyphenated slug of at most 64 characters and a valid SemVer package version. |
streaming_not_yet_implemented | 501 | no | Legacy compatibility code for older deployments where stream=true was recognized but not enabled. |
not_found | 404 | no | Requested HTTP resource or endpoint was not found. Check the path and identifier; retrying unchanged cannot succeed. |
Missing tasks, files, and voices
A *_not_found code means the ID does not exist, or it belongs to another Beatra account. Use the ID returned when the task, file, or voice was created, and check that the agent or API key belongs to the account that created it (Accounts and merging).
- Tasks: list recent ones with
beatra.tasks.listorGET /v1/tasks. - Uploaded files: upload the file again and use the new artifact ID.
- Voices: list the voices you can use with
beatra.voices.listorGET /v1/voices. A cloned voice that waits for activation expires after 7 days.
| code | HTTP | retryable | description |
|---|---|---|---|
task_not_found | 404 | no | task_id does not exist or does not belong to this account. Use the task_id returned at creation; list recent tasks with GET /v1/tasks or beatra.tasks.list. |
artifact_not_found | 404 | no | artifact_id does not exist or does not belong to this account. Upload the media again and use the newly returned artifact id. |
result_undeliverable | 502 | no | The completed result could not be delivered because it is too large, too deeply nested, or not valid JSON. Do not resubmit the same lookup. |
voice_not_found | 404 | no | voice_id does not exist or does not belong to this account. List available voices with GET /v1/voices or beatra.voices.list. |
voice_preview_expired | 422 | no | This preview voice has expired and can no longer be activated or used. Clone the voice again. |
voice_sample_rejected | 422 | no | The voice sample was rejected. See details.reason, fix the sample, and clone again with a new client_request_id. |
voice_limit_reached | 409 | no | This account already has the maximum number of cloned voices waiting for activation. Activate one, or delete one in the desktop app or with DELETE /v1/voices/{voice_id}; waiting voices also expire after 7 days. |
voice_retired | 422 | no | This voice is no longer supplied. Select another voice; details may name a replacement. The selected voice is never silently replaced. This request is not charged or is refunded. |
voice_unavailable | 422 | no | The cloned voice can no longer be restored from its saved sample. This is permanent; do not retry. Contact support. This request is not charged or is refunded; the original clone fee is not refunded. |
Still stuck
Email support@beatra.ai, or use Feedback in the console. Include:
- the
request_idfrom the error (the same value as theX-Request-Idresponse header), and the task ID when there is one; - the error
codeand message; - when it happened, and whether you used the Skill, MCP, or the REST API.
Support needs none of your API keys, the files under ~/.beatra/, or verification codes; leave them out.
Last updated