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_…"
  }
}
FieldMeaning
codestable snake_case identifier. Branch on this. Never reused, never renamed.
typethe category (table below). Use it when you do not recognise the code.
messagefor 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.
fieldthe public path of the offending input (references[2].image), or null
retryabletrue if the same request may succeed later
docsa link to the error's docs page, when available
request_idquote 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 error object, obey its retryable: retry if it is true, never if it is false — whatever the status, 5xx included.
  • Retry on 429, 500, 502, 503, 504 only when the answer has no error object (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 POST with the same Idempotency-Key so a retry cannot run a job twice (Idempotency).
  • Honour Retry-After when 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; field names it. field_not_supported is a known field the chosen variant does not use.
  • request_in_progress — the first request with this Idempotency-Key is still being processed: retry shortly with the same key.
  • insufficient_credits — the balance does not cover the hold; required and balance say 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 your X-Refabric-Start-Timeout.
  • file_not_deletable — DELETE /v1/files/{ref} on a handle that is not art: (an upload, a library item or a record); 422, type invalid_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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

Fix: Read the message and field, change that input and send again.

prompt_required

This request needs a prompt.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
400invalid_requestNo

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.

StatusTypeRetryable
400invalid_requestNo

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.

StatusTypeRetryable
413invalid_requestNo

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.

StatusTypeRetryable
400invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

Fix: Send at most the number of colours the task schema allows (maxItems).

invalid_colour

A colour is not a hex code.

StatusTypeRetryable
422invalid_requestNo

Fix: Write each colour as #RRGGBB, for example "#E8D9C4".

moodboard_required

This request needs at least one moodboard.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

Fix: Send at least one image in images.

image_not_public

An image address is not publicly reachable.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

Fix: Send a non-empty name.

invalid_weight

The weight is not a whole number of grams per square metre in the allowed range.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
415invalid_requestNo

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.

StatusTypeRetryable
413invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

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.

StatusTypeRetryable
422invalid_requestNo

Fix: Send items, colours or both.

Type: authentication

No valid API key was sent.

unauthenticated

The request carries no valid API key or token.

StatusTypeRetryable
401authenticationNo

Fix: Send Authorization: Bearer <key> with an active key.

invalid_api_key

The API key is missing, malformed, revoked or expired.

StatusTypeRetryable
401authenticationNo

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.

StatusTypeRetryable
403permissionNo

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.

StatusTypeRetryable
403permissionNo

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.

StatusTypeRetryable
403permissionNo

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.

StatusTypeRetryable
403permissionNo

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.

StatusTypeRetryable
403permissionNo

Fix: Upgrade the plan or contact support.

subscription_inactive

The account's subscription is inactive.

StatusTypeRetryable
403permissionNo

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.

StatusTypeRetryable
404not_foundNo

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.

StatusTypeRetryable
410not_foundNo

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.

StatusTypeRetryable
409conflictNo

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.

StatusTypeRetryable
409conflictYes

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.

StatusTypeRetryable
409conflictNo

Fix: Read GET /v1/jobs/{id}.

idempotency_key_reused

This Idempotency-Key was already used with a different request.

StatusTypeRetryable
409conflictNo

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.

StatusTypeRetryable
409conflictYes

Fix: Retry shortly with the same key and the same request.

cancelled

The job was cancelled before it finished.

StatusTypeRetryable
409conflictNo

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.

StatusTypeRetryable
409conflictNo

Fix: Add colours to a fabric made with fabric.create.

fabric_not_ready

The fabric is still being made, or its making failed.

StatusTypeRetryable
409conflictNo

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.

StatusTypeRetryable
402insufficient_creditsNo
ctx keyTypeMeaning
requiredintegerThe credits this request needs.
balanceintegerThe 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.

StatusTypeRetryable
429rate_limitedYes
ctx keyTypeMeaning
retry_afterintegerSeconds 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.

StatusTypeRetryable
422content_refusedNo

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.

StatusTypeRetryable
422processing_failedNo

Fix: If retryable is true, send the request again; otherwise change the inputs.

images_not_fetchable

None of the images could be read.

StatusTypeRetryable
422processing_failedNo

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.

StatusTypeRetryable
422processing_failedNo

Fix: Send clearer photos of garments or looks.

capacity_busy

Too many of your jobs are running at once.

StatusTypeRetryable
422processing_failedYes

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.

StatusTypeRetryable
503internalYes

Fix: Retry the request with the same Idempotency-Key.

internal

Something went wrong on our side.

StatusTypeRetryable
500internalYes

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.

StatusTypeRetryable
200warningNo

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.

StatusTypeRetryable
200warningNo

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.

StatusTypeRetryable
200warningNo

Fix: Check those layers before cutting or printing; the rest is complete.

already_4k

The image is already 4K; nothing was charged.

StatusTypeRetryable
200warningNo

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.

StatusTypeRetryable
200warningNo

Fix: Nothing to do: the kit already holds the item. Send each url once.

view_generated

This view was newly made.

StatusTypeRetryable
200warningNo

Fix: Nothing to do: the product had no saved copy of this view, so it was made as usual.