Troubleshooting
Troubleshooting
Section titled “Troubleshooting”Image generation returns stable error codes so you can tell exactly what went wrong. This page maps the ones you’re most likely to hit to a fix. For the full list, see the reference.
Requests return 401
Section titled “Requests return 401”Codes: missing_session, session_invalid, unknown_bearer_scheme, missing_workspace_header.
missing_session/session_invalid— yourimagegen_sessioncookie is missing or no longer valid. Sign in again at account.destesi.io, then retry.unknown_bearer_scheme— you sent anAuthorization: Bearerheader whose value isn’t anidn_pat_token. Once aBearerheader is present there is no fallback to the cookie. Mint a Personal Access Token at account.destesi.io/settings/api-tokens.missing_workspace_header— a token was sent withoutX-Destesi-Workspace. A token spans every workspace you belong to, so the header is what selects one.
Also check the host: the API lives at https://api.imagegen.destesi.io. https://imagegen.destesi.io is the web app and will not serve API routes.
The engine you want is unavailable
Section titled “The engine you want is unavailable”Codes: unknown_engine (400), engine_not_connected (409), engine_revoked (409).
unknown_engine— theengineid isn’t one this service offers. CallGET /v1/enginesfor the real list; omitengineentirely to use the fast engine.engine_not_connected— the engine runs on an account you haven’t connected. The high-quality engine uses your own OpenAI account: connect OpenAI in Connect and it becomes available.engine_revoked— you connected it, but the credential has since been revoked. Reconnect it in Connect.
Until the account is connected, the engine still appears in GET /v1/engines with available: false — so a client can show it as a disabled option rather than hiding it.
A dimension or step count is rejected
Section titled “A dimension or step count is rejected”Codes: invalid_width, invalid_height, invalid_steps (400).
width and height are a fixed set — 512, 576, 768, 1024 — not a free range, and steps is capped at 50. Values outside those are refused rather than rounded, so you’re never handed an image at a size you didn’t ask for.
Pick one of the four sizes, and keep steps at or below 50.
A render times out
Section titled “A render times out”Code: deadline_exceeded (504).
POST /v1/generate waits for the image synchronously, with a 120-second ceiling.
- For long renders, switch to the streaming endpoint
POST /v1/generate-and-stream— it keeps the connection open while the job runs, with no per-request deadline. - If you run your own worker, put it on a CUDA GPU. Renders that take minutes on CPU take seconds on a GPU.
You’re at your plan allowance
Section titled “You’re at your plan allowance”Code: 429.
Generations per month and concurrent jobs in flight are metered per workspace and set by your plan. Wait for in-flight jobs to finish, or move to a plan with a larger allowance.
A related 503 quota_policy_unavailable means the service couldn’t resolve your allowances at all — it refuses the request rather than serving it unmetered. That’s a service-side issue; retry shortly.
Generation returns drive_unavailable
Section titled “Generation returns drive_unavailable”Code: drive_unavailable (502 or 503).
Every image is registered in Drive, so Drive is a hard requirement — image generation refuses to produce an image it can’t store.
- As a user: this is a service-side configuration issue, not something you did. Retry shortly; if it persists, report it.
- As an operator: confirm
SUITE_TOOL_SECRETis set (and matches Drive’s), and thatDRIVE_API_URLpoints at a reachable Drive service. A missingSUITE_TOOL_SECRETmakes the Drive client non-functional and every generate call fails this way. A transient502on the streaming path is retried automatically up to three times before the stream closes with this code.
Jobs stay queued and never finish (self-hosted worker only)
Section titled “Jobs stay queued and never finish (self-hosted worker only)”Symptom: queued events stream but you never reach progress or done; eventually the stream ends with timeout. The Chat image tool returns “no worker registered”.
There’s no worker draining the job queue. The worker is intentionally a separate, heavyweight process (it loads a multi-gigabyte model), so it’s started on its own.
The most common root cause is a queue mismatch between the API and the worker:
- They must point at the same Redis database number (
IMAGEGEN_REDIS_URL— the default is database2). If the API enqueues to one database and the worker listens on another, the worker silently never sees the jobs. - They must agree on the queue name. The API’s queue name is fixed in code (
bull:create-av:v2:imageGeneration), so leave the worker’sIMAGEGEN_QUEUE_NAMEat its matching default.
Generation fails mid-render
Section titled “Generation fails mid-render”Codes: job_failed, job_incomplete (502).
The worker started but couldn’t finish.
job_failed— the model reported an error during generation. On constrained hardware this is often out-of-memory. Try a smaller resolution (e.g.width/heightof768instead of1024) or fewersteps.job_incomplete— the job reported done but no image came back. Retry the request; if it recurs, it points at a service-side problem worth reporting.poll_failed(502) — the service lost track of the job while waiting for it. Retry.streaming_not_supported(500) — the connection can’t stream Server-Sent Events, usually because a proxy is buffering the response. Use the non-streamingPOST /v1/generateinstead.
An image URL stops loading
Section titled “An image URL stops loading”Codes: signature_expired (410), signature_invalid (401), or a plain 404.
The image_url returned by a generate call is a time-limited link, and the short-lived result endpoint only serves a job for 1 hour after it completes.
The durable copy of every image lives in Drive. Use the drive_file_id from the generate response to find it in your workspace’s ImageGen generated folder and get a fresh link, rather than holding onto an image_url.
Bad request
Section titled “Bad request”Codes: missing_prompt, invalid_json (400).
missing_prompt— thepromptfield was empty. A prompt is required.invalid_json— the request body wasn’t valid JSON. Check yourContent-Type: application/jsonheader and the payload.