For AI agents: this page is also available as Markdown at https://docs.refabric.com/task-apis/errors/task-errors.md, and the index of every page is https://docs.refabric.com/llms.txt.
Task APIs › Errors
Errors
Every error has one shape, in HTTP responses and inside a failed job.
HTTP 422
{
"error": {
"code": "too_many_references",
"type": "invalid_request",
"message": "The request sends more reference images than the task takes.",
"field": "references",
"retryable": false,
"request_id": "req_…"
}
}| Field | Meaning |
|---|---|
code | stable snake_case identifier. Branch on this. Never reused, never renamed. |
type | the category (table below). Use it when you do not recognise the code. |
message | for developers; says how to fix it. It is always one of Refabric's own sentences. May be reworded at any time — do not parse it. |
field | the public path of the offending input (references[2].image), or null |
retryable | true if the same request may succeed later |
docs | a link to the error's docs page, when available |
request_id | quote it when you contact support |
The response also carries X-Request-ID and X-Refabric-Error-Type: <type>.
Errors inside a job
A failed job carries the same object in its error — on GET /v1/jobs/{id} and in the webhook.
The job's own job_id is beside it; request_id is null (the error was not an answer to a
request). A Prefer: wait submit that fails answers the error itself, with job_id inside it.
{ "job_id": "j_…", "lifecycle": "terminal", "outcome": "failed",
"error": { "code": "start_timeout", "type": "internal",
"message": "The job could not be started in time.",
"field": null, "retryable": true, "request_id": null } }Failed jobs use processing_failed, content_refused, insufficient_credits or internal
(start_timeout is internal, as above; live list: GET /v1/vocab/error_type). A cancelled job carries code: cancelled
(type: conflict, retryable: false) — on GET /v1/jobs/{id}, in the webhook and in a
Prefer: wait answer (409) — never null.
A refused prompt or image is content_refused. A job that delivers no output fails with
processing_failed (retryable: false) (live list: GET /v1/vocab/error_type).
Reading the result of a job that did not succeed answers an error, not an empty result:
409 job_failed for a failed job ("This job failed; its reason is the job read's error." — read
GET /v1/jobs/{id}), 409 cancelled for a cancelled one (type: conflict, as everywhere a
cancelled job is reported), 409 result_not_ready while it still runs.
Warnings
A job that succeeded can report warnings in summary.warnings[]:
"summary": { "requested": 3, "delivered": 2,
"warnings": [ { "code": "output_not_produced", "field": "back",
"message": "One output of this job could not be produced; `field` names which." } ] }Each row is {code, field, message}: code is catalogued with the errors (type warning,
GET /v1/errors), field names the output or input it is about (back, poses.items[1],
images[4]) or is null. Branch on code, as for errors.
The list of warning codes, with what each means, is GET /v1/errors (the entries of type
warning); it grows as tasks learn to report more, so read it there rather than from this page.
An unknown warning code is safe to show as its message.
Retrying
- When the answer carries an
errorobject, obey itsretryable: retry if it istrue, never if it isfalse— whatever the status,5xxincluded. - Retry on
429,500,502,503,504only when the answer has noerrorobject (an error from a proxy or load balancer in front of us), and on a network error. - Use exponential backoff with jitter (for example 1 s, 2 s, 4 s … capped at 60 s).
- Always resend a
POSTwith the sameIdempotency-Keyso a retry cannot run a job twice (Idempotency). - Honour
Retry-Afterwhen present.
import random, time, requests
RETRY_STATUS = {429, 500, 502, 503, 504}
def call(session, method, url, **kw):
for attempt in range(6):
try:
r = session.request(method, url, timeout=90, **kw)
except requests.ConnectionError:
r = None
if r is not None and r.status_code < 400:
return r
if r is not None:
try:
err = r.json().get("error")
except ValueError:
err = None # not our envelope (a proxy's error page)
if err is not None and not err.get("retryable"):
raise RuntimeError(f"{err.get('code')}: {err.get('message')} ({err.get('request_id')})")
if err is None and r.status_code not in RETRY_STATUS:
r.raise_for_status()
wait = float(r.headers.get("Retry-After", 0)) if r is not None else 0
time.sleep(max(wait, min(60, 2 ** attempt) + random.random()))
r.raise_for_status()The codes
Every code the server answers — its type, HTTP status, message and fix — is listed live by
GET /v1/errors. That catalogue is the one list. The codes below are listed from that catalogue, and the task
pages and Panel › Developers › Errors link to the code's entry here.
Branch on type for anything you do not recognise.
A few codes are worth knowing by name:
field_not_accepted— you sent a field the task does not take (a misspelled name, for example) or one the server fills itself;fieldnames it.field_not_supportedis a known field the chosen variant does not use.request_in_progress— the first request with thisIdempotency-Keyis still being processed: retry shortly with the same key.insufficient_credits— the balance does not cover the hold;requiredandbalancesay by how much (Pricing).too_many_outputs— a shoot that would make more images than its task allows.start_timeout— the job could not start before yourX-Refabric-Start-Timeout.file_not_deletable—DELETE /v1/files/{ref}on a handle that is notart:(an upload, a library item or a record);422, typeinvalid_request,field: null.
Type: invalid_request
The request cannot be used as sent; fix it and send again.
invalid_request
A field is missing or has a value this task cannot use.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Read field and the task's input schema (GET /v1/tasks/{name}), correct the value and send again.
field_not_accepted
The request sends a field the task does not take, or one Refabric sets itself.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Remove the fields the message names (field names it when there is one). The task's input schema (GET /v1/tasks/{name}) lists every field it takes.
field_not_supported
The request sends a field that is not used with the other values it sends.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Remove the field named in field; the message says why. The task schema shows the fields each kind or type takes (its oneOf).
invalid_option
A value is not one of the options this field offers.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Pick one of the values listed for the field in the task schema or at GET /v1/vocab/{name}.
request_refused
The request is well-formed but this task cannot work with it.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Read the message and field, change that input and send again.
prompt_required
This request needs a prompt.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Write prompt. The task's prompt field says when it may be left out.
too_many_references
The request sends more reference images than the task takes.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at most the number of references the task schema allows (maxItems).
moodboard_not_ready
The moodboard is still being analysed, or its analysis failed.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Wait until GET /v1/files/{moodboard} shows the analysis, or choose another moodboard.
brand_kit_look_not_ready
The brand kit look you referenced has not finished its analysis.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Wait until the look is ready in the brand kit, or send it without use_case: frame.
api_key_in_query
An API key was sent in the URL. Your key may have leaked — rotate it.
| Status | Type | Retryable |
|---|---|---|
| 400 | invalid_request | No |
Fix: Roll or revoke the key now on the API keys page of your account, then send keys only in the Authorization header, never in a URL.
malformed_request
The request cannot be read as it was sent: a header, or the body's form.
| Status | Type | Retryable |
|---|---|---|
| 400 | invalid_request | No |
Fix: Read the message and field: send the body as valid JSON, and each header in its documented form.
body_too_large
The request body is larger than this operation takes.
| Status | Type | Retryable |
|---|---|---|
| 413 | invalid_request | No |
Fix: Send a smaller body; the limit is in the message and at GET /v1/meta (limits.request.max_body_bytes).
job_already_ended
The job has already ended.
| Status | Type | Retryable |
|---|---|---|
| 400 | invalid_request | No |
Fix: Read GET /v1/jobs/{id} for how it ended; start a new job to run the work again.
moodboard_needs_images
A moodboard needs more images.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at least as many images as the task schema asks for (minItems of images).
too_many_images
The request sends more images than the task takes.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at most the number of images the task schema allows (maxItems).
too_many_items
The request sends more items of one type than the task takes.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at most as many items of each type as the task takes; the message names the number.
too_many_colours
The request sends more colours than the task takes.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at most the number of colours the task schema allows (maxItems).
invalid_colour
A colour is not a hex code.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Write each colour as #RRGGBB, for example "#E8D9C4".
moodboard_required
This request needs at least one moodboard.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Name one or more moodboards in moodboards, as ["moodboard:<id>"] (GET /v1/refs/moodboard, ?curated=true for Refabric's own).
look_not_in_moodboard
A look is not a look of any moodboard the request names.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send a look url from one of the named moodboards (data.items[].url of GET /v1/files/moodboard:<id>), or name the moodboard it belongs to.
images_required
This request needs at least one image.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send at least one image in images.
image_not_public
An image address is not publicly reachable.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send a public https url, or a file from an earlier result (art:…) or an upload (file:…).
name_required
This request needs a name.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send a non-empty name.
invalid_weight
The weight is not a whole number of grams per square metre in the allowed range.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send facts.weight_gsm as a whole number, e.g. 180, or leave it out to have it filled in for you.
file_not_deletable
The API deletes the files a job produced, named by their art:… handle.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send the art:… handle of a file a job produced.
unsupported_media_type
The body, or the uploaded file, is of a media type this operation does not take.
| Status | Type | Retryable |
|---|---|---|
| 415 | invalid_request | No |
Fix: Send the body as application/json (an upload also takes multipart/form-data), and upload a PNG, JPEG, WebP, GIF, BMP or PDF file in the file part — or register its url instead.
file_too_large
The uploaded file is larger than the upload limit.
| Status | Type | Retryable |
|---|---|---|
| 413 | invalid_request | No |
Fix: Send a smaller file (the limit is in the message), or register a url of it instead.
too_many_outputs
The request asks for more images than one shoot makes.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send fewer products, models, poses or views; the limit is in the message.
image_not_from_shoot
An image is not an image of one of your shoots, or the images come from two shoots.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send images of ONE shoot: the data.items[].url of GET /v1/files/photoshoot:<id>.
image_has_no_model
Which model this image shows is not known.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send an image from photoshoot.create or mannequin_photoshoot.create, or an edit of one — or name the face with model (model:<id>, GET /v1/refs/model).
kit_empty
A brand kit needs items, colours or both.
| Status | Type | Retryable |
|---|---|---|
| 422 | invalid_request | No |
Fix: Send items, colours or both.
Type: authentication
No valid API key was sent.
unauthenticated
The request carries no valid API key or token.
| Status | Type | Retryable |
|---|---|---|
| 401 | authentication | No |
Fix: Send Authorization: Bearer <key> with an active key.
invalid_api_key
The API key is missing, malformed, revoked or expired.
| Status | Type | Retryable |
|---|---|---|
| 401 | authentication | No |
Fix: Send Authorization: Key rf_live_… with an active key. Create or roll keys from your account.
Type: permission
Your key or your plan does not allow this.
permission_denied
Your account or plan does not allow this.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Check which tasks your plan includes, or contact support to change it.
api_key_not_allowed_here
An API key was sent from a browser.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Call the API from your server: a key in a web page or an app a user can read is a leaked key. Keep keys server-side.
scope_missing
Your API key's scopes do not include this action.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Create a key with the scope this action needs, or add it to the key.
session_required
This endpoint is not part of the public API; an API key cannot call it.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Use the public endpoints listed in the API reference. Manage API keys and webhook endpoints in the panel, signed in to your account.
api_access_not_included
Your plan does not include API access.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Upgrade the plan or contact support.
subscription_inactive
The account's subscription is inactive.
| Status | Type | Retryable |
|---|---|---|
| 403 | permission | No |
Fix: Renew the subscription, then retry.
Type: not_found
Nothing of yours has this address, or it was removed.
not_found
The task, job or file does not exist, or it is not yours.
| Status | Type | Retryable |
|---|---|---|
| 404 | not_found | No |
Fix: Check the name or id. Ids from another account are not visible to you.
task_removed
This task was removed. It was deprecated first and is no longer served.
| Status | Type | Retryable |
|---|---|---|
| 410 | not_found | No |
Fix: Use the replacement the changelog's Removed: entry names; GET /v1/tasks lists the current tasks.
Type: conflict
The request conflicts with the current state of what it names.
conflict
The request conflicts with the current state of the resource.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Read the message; wait for the resource to change, or send a different request.
result_not_ready
The job has not finished successfully, so it has no result yet.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | Yes |
Fix: Poll GET /v1/jobs/{id} until it has finished, then read the result.
job_failed
This job failed; its reason is the job read's error.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Read GET /v1/jobs/{id}.
idempotency_key_reused
This Idempotency-Key was already used with a different request.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Use a new key for a different request; reuse a key only to retry the same request.
request_in_progress
The first request with this Idempotency-Key is still being processed.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | Yes |
Fix: Retry shortly with the same key and the same request.
cancelled
The job was cancelled before it finished.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Nothing to fix: the job was cancelled (by you, or by us with a reason in message). Send the request again if you still want its result.
fabric_not_recolourable
This fabric was not made with fabric.create.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Add colours to a fabric made with fabric.create.
fabric_not_ready
The fabric is still being made, or its making failed.
| Status | Type | Retryable |
|---|---|---|
| 409 | conflict | No |
Fix: Wait until GET /v1/files/fabric:<id> shows status: ready, then send again.
Type: insufficient_credits
Your balance does not cover this request.
insufficient_credits
Your balance does not cover this request.
| Status | Type | Retryable |
|---|---|---|
| 402 | insufficient_credits | No |
ctx key | Type | Meaning |
|---|---|---|
required | integer | The credits this request needs. |
balance | integer | The credits your balance holds now. |
Fix: Top up credits; /estimate shows what the request needs.
Type: rate_limited
Too many requests; wait and retry.
rate_limited
Too many requests in a short time.
| Status | Type | Retryable |
|---|---|---|
| 429 | rate_limited | Yes |
ctx key | Type | Meaning |
|---|---|---|
retry_after | integer | Seconds to wait before the next call. |
Fix: Wait for the number of seconds in the Retry-After header, then retry.
Type: content_refused
The inputs were refused.
content_refused
The inputs were refused.
| Status | Type | Retryable |
|---|---|---|
| 422 | content_refused | No |
Fix: Change the prompt or the images. Sending the same request again will be refused again.
Type: processing_failed
The job ran and failed.
processing_failed
The job ran and failed.
| Status | Type | Retryable |
|---|---|---|
| 422 | processing_failed | No |
Fix: If retryable is true, send the request again; otherwise change the inputs.
images_not_fetchable
None of the images could be read.
| Status | Type | Retryable |
|---|---|---|
| 422 | processing_failed | No |
Fix: Send image URLs that are public and reachable, or files from an earlier result.
no_brand_dna
None of the images could be used.
| Status | Type | Retryable |
|---|---|---|
| 422 | processing_failed | No |
Fix: Send clearer photos of garments or looks.
capacity_busy
Too many of your jobs are running at once.
| Status | Type | Retryable |
|---|---|---|
| 422 | processing_failed | Yes |
Fix: Wait for some to finish, then send the request again.
Type: internal
Something went wrong on our side.
start_timeout
The job could not be started in time.
| Status | Type | Retryable |
|---|---|---|
| 503 | internal | Yes |
Fix: Retry the request with the same Idempotency-Key.
internal
Something went wrong on our side.
| Status | Type | Retryable |
|---|---|---|
| 500 | internal | Yes |
Fix: Retry. If it keeps happening, contact support with the request_id.
Type: warning
Not an error: a note on a job that succeeded.
output_not_produced
One output of this job could not be produced; field names which.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Nothing is charged for it. Send a request for that output alone to try again.
image_not_fetchable
One of the images you sent could not be read, so it was left out; field names which.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Send image URLs that are public and reachable, or files from an earlier result.
svg_needs_review
Some shapes of the SVG are on layers whose names contain Unassigned.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Check those layers before cutting or printing; the rest is complete.
already_4k
The image is already 4K; nothing was charged.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Nothing to do: the file holds the image's own pixels as a new file of this job.
item_duplicate
This url is already in the kit; it was not added twice.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Nothing to do: the kit already holds the item. Send each url once.
view_generated
This view was newly made.
| Status | Type | Retryable |
|---|---|---|
| 200 | warning | No |
Fix: Nothing to do: the product had no saved copy of this view, so it was made as usual.