Warnings & Error Codes
Reference catalog for the Import Status response: every warnings[] code, every 4xx error code, and the build-phase failure codes that populate error on a FAILED status.
Warnings
warnings[] is append-only across polls — entries added in earlier PROCESSING responses remain in the array on DONE. Warnings never fail a request; they record auto-correction decisions made during processing.
| Code | Emitted by | Meaning |
|---|---|---|
font_weight_adjusted | GET status | Requested font weight is unavailable; the nearest available match was substituted. |
text_fit_failed | GET status (non-strict) | Text could not fit the bounding box even at min_font_size — the layer renders at the floor size. Pass ?strict=true on the POST to make this fail the import instead. |
preview_generation_failed | GET status (on DONE) | One or more previews failed to render. The import still completes — the design is created, and the thumbnail is taken from whichever format did render (it may be missing when none did). Path is formats on static / animated / printer. On printer_multipage you get one warning per failing page at pages[i] (or a single bare pages when the page list can't be resolved). |
property_not_representable | GET status / GET as-import | The stored design carries a property the import schema does not model, so it was omitted from the exported payload. Carries both path and code. This is about what the design holds, not about anything you sent — a benign editor-internal parameter is the usual cause. |
property_dropped_for_type | GET status | A property the design type cannot render was accepted and removed from the imported design rather than failing the request: shadow, text_shadow, pattern_* and overlay_* on printer / printer_multipage. One warning per occurrence, naming the layer path and the property; the rest of the layer is imported unchanged. Gradient colours are the one print case still rejected with unsupported_for_type, because print collapses a gradient to its first stop. |
color_converted | GET status / GET as-import | A colour was converted into the design type's colour space: hex → cmyk(...) on printer / printer_multipage, cmyk(...) → hex on static / animated. The message names the path and both values. Conversion is approximate — it uses no ICC profile — so if exact print colour matters, author in cmyk(...) directly and no conversion happens. Gradients on print designs are not converted; they are rejected with unsupported_for_type, because flattening a gradient to a single colour would silently change the design. |
print_settings_not_recoverable | GET as-import | Print designs only. The design's stored print settings could not be read, or — on printer_multipage — an older design's stored pages disagree with each other and the uniform top-level shape cannot represent them. Emitted at width/height/unit, bleed_size, safe_size or dpi (on multipage) or once at formats (otherwise). See Export a Design. |
animation_duration_derived | GET as-import | Animated designs only. The exported animation.duration had to be derived from element timing because the design carried no stored timeline length (older designs). Path is animation.duration. |
Warnings without a code
A warning entry carrying only a message (no code) is purely informational — a human-readable note with no stable machine identity, and safe to log and ignore. Only branch on warnings that carry a code.
Error codes
Design Import errors use the same envelope as the rest of the API: a top-level id and message, plus an errors array whose entries each carry a path, a stable machine-readable code, a human message, and optional expected / received hints:
{
"id": "out_of_range",
"message": "font_size must be between 2 and 1000",
"errors": [
{
"path": "layers[2].properties.font_size",
"code": "out_of_range",
"message": "font_size must be between 2 and 1000",
"expected": { "min": 2, "max": 1000 },
"received": 1500
}
]
}Because a rejected payload usually fails in several places at once, errors is where the detail lives. The top-level id is the shared code when every entry agrees, and invalid_payload when they differ.
The path convention
Paths are uniformly bracketed: array indices always use [n], never a dot. formats[0].width, pages[1].layers[0].properties.color, layers[2].animation.tweens[0].keyframes[1]. There is no dotted-index form — if you have string-matching code that expects formats.0.width, it is matching an older build.
Which expected / received you get
Both hints are best-effort, but two codes now reliably carry expected:
| Code | expected | received |
|---|---|---|
out_of_range | { min, max } (or { max } for a ceiling) | The offending value, usually |
unknown_enum_value | The full array of allowed values | The offending value, usually |
missing_assets | The list of missing upload targets, when known | — |
One exception: presigned uploads
Everything the Abyssale API answers uses the envelope above. The one body that does not is a failed presigned upload, which is S3's own response and never reaches Abyssale:
<Error><Code>EntityTooLarge</Code>…</Error>See Upload Assets.
| Code | Endpoint | Meaning |
|---|---|---|
missing_required | POST | A required field is absent — e.g. omitting pages on a printer_multipage payload. |
unknown_field | POST | The payload contains a field not in the schema — including a field that belongs to another design type in this position: formats / layers on printer_multipage (use top-level print setup + pages instead), any print-setup field or a name inside a pages[i] object (a page accepts only background_color and layers), z_position on any layer, or a qrcode error_correction_level. |
wrong_type | POST | A field has the wrong type (e.g. string where int expected). |
out_of_range | POST | A numeric field is outside its allowed range, expected = { min, max } — this includes an empty layers array (expected: { min: 1, max: 80 }), at the top level, on animated, and per multipage page. On print imports, also fires when a physical-unit value exceeds the platform's pixel limits at 300 DPI — the message includes the computed pixel value. Also fires when a dpi exceeds its area-based ceiling (printer: at formats[i].dpi; printer_multipage: at the top-level dpi, against the single document size). |
unknown_enum_value | POST | An enum field received a value not in its allowed set. Allowed values are returned in expected. |
unknown_format_key | POST | A layout or properties key references a format not declared in formats[]. |
duplicate_layer_name | POST | Two layers share the same name. |
duplicate_format_name | POST | Two formats share the same name. |
reserved_format_name | POST | A format is named the literal string default (reserved as the merge sentinel). |
project_not_found | POST | 400. target.project_uuid does not reference a project owned by the caller's company, or the project is no longer in CREATED state. Reported at target.project_uuid, alongside the other body-validation errors. |
conditional_dependency_missing | POST | A field that another field requires is missing, or a cross-reference doesn't resolve. Examples: mask_name: "rounded_corners" without mask_properties.radius; filter_name: "duotone" without filter_properties; a group layer_ids entry naming a layer that doesn't exist, reported at layers[i].layer_ids[k] — and on printer_multipage, one naming a layer on a different page (group membership is page-scoped), at pages[i].layers[j].layer_ids[k]. |
unknown_font | POST | The font UUID doesn't exist (or is deleted). |
unreachable_src | POST | An https:// src could not be reached during validation. |
unsupported_for_type | POST | A field or value is only valid on another design type, or not allowed in this position. Full list. |
invalid_payload | POST | Catch-all when no more specific code applies. Common cases. |
missing_assets | PUT · GET | One or more presigned uploads were never completed (422; expected lists the missing targets), or the presigned upload window expired before validation — see Import Status → Abandoned imports terminate. |
template_import_already_processed | PUT | The import is past the QUEUED state and can't be re-validated. 409. The message names the import's public status only. |
not_round_trippable | GET as-import | The design uses features or values that cannot be expressed as an import payload — including an export in which every layer had to be dropped, which is returned as this error rather than an importable empty payload. |
not_found | GET · PUT | The import id is unknown, or belongs to another company. 404, reported at path: "id". |
template_not_found | Designs endpoints | The design UUID is unknown or belongs to another company. 404. The same code every design lookup returns — GET /designs/{id}/as-import briefly used a separate design_not_found, which is gone. |
template_not_found | Generation endpoints | The template UUID is unknown or belongs to another company. 404. Predates the template-import surface — kept for the older generation routes. |
invalid_query_param | Any | A query parameter's value could not be parsed (e.g. ?validate_only=banana). 400, with the parameter name in path. Unknown query parameters are ignored rather than rejected. |
unauthorized | Any | Missing or invalid API key. 401. |
feature_not_in_plan | POST | 429. Your plan does not include the design type you are importing — MP4 for animated, printable PDF for printer and printer_multipage. Carries no errors[]: the payload is fine, the plan is the problem. See Plan requirements. |
endpoint_not_found | Any | No route matches the method + path. 404. |
internal_error | Any | An unexpected server-side failure — 500. Safe to retry a GET; do not blindly retry a POST. |
unsupported_for_type
The value is well-formed but does not belong on this design type, or in this position:
| On | What is rejected |
|---|---|
static | cmyk(...) colour tokens · TIFF sources · unit / bleed_size / safe_size / dpi |
printer / printer_multipage | linear-gradient(...) colours — a supported static feature, just not a valid print colour token |
Any type but animated | A top-level or per-layer animation object |
animated | Group auto_layout / direction / placement / gap |
| Any type | tweens on a group layer · a video layer inside a group's layer_ids · a media extension (.mp4, .webm, .mp3, .wav) on an image or logo src |
Two things this is not:
- A solid hex on a print design is converted for you, with a
color_convertedwarning. - Properties print cannot render —
shadow,text_shadow,pattern_*,overlay_*— are dropped with aproperty_dropped_for_typewarning rather than rejected.
See Print Imports and Animated Imports.
invalid_payload
Common cases, in rough order of how often they come up:
- A flat
layout/propertiesobject on a multi-format design, where each format must be keyed. The reverse — a keyed object on a single-format design — is accepted. - A malformed colour token: a CMYK component outside 0–100, a
%inside one, a hash-less hex, or a gradient that does not match the grammar. A well-formed token on the wrong design type isunsupported_for_typeinstead. - A data URI whose payload is not valid base64.
- An animation keyframe missing a numeric
data.time, a tween with fewer than 2 keyframes, or a duplicate tween type on one layer. - Non-contiguous
videolayers — any non-video layer,audioincluded, between two videos. - A
payloadlonger than its maximum on atext,buttonorqrcodelayer.
Build-phase failures (the error object)
The error object on a FAILED status uses the same single-entry shape and is reserved for failures during backend processing:
| Code | Path | Meaning |
|---|---|---|
text_fit_failed | layers[i].properties.font_size | Text could not fit its bounding box at any allowed size, under ?strict=true. The message excerpts the text rather than echoing the whole payload. |
image_processing_failed | layers[i].properties.src | An image asset is in a format the pipeline does not recognise or support. Scoped to unsupported formats — a file that is recognised but damaged is invalid_asset. Never raised for video/audio. |
media_processing_failed | layers[i].properties.src | A video or audio asset could not be decoded or processed — an unsupported container, or a file whose extension and contents disagree. |
invalid_asset | layers[i].properties.src | The asset arrived but could not be decoded. Covers a corrupt or truncated image (on printer and static alike — previously this leaked a raw image-library message as image_processing_failed at path: "result"), and video or audio bytes that are not really media at all, such as an image or a text file uploaded under a .mp4 name (previously accepted, reaching DONE with a broken asset). |
font_resolution_failed | layers[i].properties.font | The font could not be resolved or loaded at build time. |
import_failed | result | Fallback for any build failure without a more specific cause. The message carries whatever detail the backend could recover — treat it as unclassified and retry the import once before investigating. |
On a multi-format design the asset paths carry the format key: layers[i].properties.<format>.src.
Media validation is a decode check, not a full inspection
Only undecodable media is rejected. A video or audio file whose duration cannot be probed is still accepted — video_duration is display-only and stays best-effort, so a missing duration never fails an import.
Preview rendering never fails an import: a failed preview ends the import DONE with a preview_generation_failed warning instead (see Warnings).
