Look up any error the SDK reports, see what triggers it, and decide whether your code or the model handles it.
The terms, defined in Terminology: the executor is a container from IMG.LY’s image that runs CE.SDK, IMG.LY’s design engine, for one conversation (a chat or a job); a design is a CE.SDK scene of pages and the blocks on them (its text, images, and shapes); your runner is your backend code that runs the agent loop and calls the tools.
Two Readers#
A failure inside a tool call goes to whoever can fix it.
- The model. When the model can fix the failure (a wrong argument, code
that threw, a design version your store no longer holds), the tool call
resolves with
isError: trueand a text that names the fix. Hand it to the model as a failed call. It never contains a stack. - Your code. When the model cannot fix it (no executor to run the engine,
a refused charge, your store down), the tool call’s promise rejects with a
CoDesignError. Your agent loop decides whether to retry, tell the person, or end the run. The message is written for a person; the underlying stack is on the error’scause.
Your own calls on codesign, the object prepareCoDesign returns
(create(), load(), export(), edit(), and handshake(), the check that
an executor can serve your setup), have no model to answer, so every kind
rejects them with a CoDesignError, also a kind a tool call hands to the
model. The tables below say who gets each kind from a tool call.
interface CoDesignError extends Error { readonly kind: CoDesignErrorKind; // open: a later SDK adds kinds readonly design?: string; // the design involved, when one is readonly source?: string; // source_failed, invalid_asset, refused, invalid_options: the asset source involved readonly retryAfterMs?: number; // executor_capacity: how long to wait, when the executor said readonly saver?: string; // older_saver: the CE.SDK version that tried to save readonly recorded?: string; // older_saver: the CE.SDK version that saved what is stored}Check an error with isCoDesignError(err), which also recognizes an error
from a second copy of the SDK in your bundle, where instanceof would not,
then switch on err.kind with a default, because the set of kinds is open.
A kind’s name and its facts (design, source, retryAfterMs, saver,
recorded) stay stable; read them rather than the message, whose words can
change. CoDesignErrorKind also lists unsaved_changes, which is reserved: the SDK
does not raise it, and your default branch covers it.
Refusing From Your Own Code#
A member you write says “no, and here is why” by throwing refusal(text):
the kind is refused, and text is what the model reads. From
designs.write, a source’s uploadFile, or uploadExport, the tool call
answers the model with text; from one of your own tools, it throws like
any error of your tool. designs.write reports a conflict by resolving
undefined (throwing kind design_conflict counts the same). See
API Reference.
Watching Every Failure#
A listener in events sees each tool call’s error.kind
( Watching Each Call):
for a call the model reads as failed, a kind below or one of the
codes the model reads; for a call that rejected, the
error’s kind; for one your signal canceled, 'aborted'.
Setup#
These are thrown when you build the tools, or when a session first opens. Retrying cannot help; fix what the message names. A source (asset source) is a list of files the engine can search and place, such as your photos or brand fonts, which one of your plugins (setup code the engine applies) registers ( Terminology).
| Kind | When | Who | What to do |
|---|---|---|---|
invalid_options |
prepareCoDesign, a session’s first open, your own codesign.edit(), or assertCanSave got input it cannot use; the cases are listed below the table. |
Your code | Fix the option the message names. For a source, run testAssetSource in your tests. |
tool_name_clash |
prepareCoDesign: one of your tools has a name the SDK’s own tools use, or two of yours share a name. |
Your code | Rename the tool the message names. |
invalid_options is raised in these cases:
prepareCoDesignhas nogateway, anuploadExportthat is not a function, apluginsentry that is not{ module, options? }, or a catalog entry (googleFonts,cesdkDefaults, orcesdkDemo) with wrong options.- When a session opens, one of your sources fails the SDK’s checks, or
designs.listSourceIdnames a source no plugin registered (sourcenames it). - In your own
codesign.edit(),argsis not JSON, orcodeis neither a string nor a function expression. assertCanSavewas given a version that is not a CE.SDK version.- For
./cesdk-utils, see Errors of the Other Entry Points.
Executors#
Each conversation’s executor is the one your acquire function (the one you
pass to remoteExecutors) answers. A design’s engine session is the engine
that holds it open on the executor between calls.
| Kind | When | Who | What to do |
|---|---|---|---|
executor_unreachable |
acquire answered undefined; the executor did not answer; a proxy in front of it answered 502 or 504. |
Your code | Retry for a short while and tell the person they are waiting. If it lasts, acquire has no executor to hand out. |
executor_capacity |
The executor is shutting down after its conversation ended and takes no new session (HTTP 503). A call that opens a design waits up to 60 seconds, at the executor’s Retry-After pace, before it rejects; any other call rejects at once. retryAfterMs carries the executor’s hint. |
Your code | The SDK has already waited; wait retryAfterMs (or a few seconds) and call again. If it lasts, check that your acquire answers a new executor once the old one is gone. |
executor_bound |
acquire answered an executor that already serves another conversation: an executor serves only the first conversation that opens a design on it, and the binding survives a restart of its container. |
Your code | A bug in acquire: give each new conversation an unused executor, and the same one while it lasts. Retrying cannot help. |
executor_version |
The executor speaks another wire protocol (the format of the messages runner and executor exchange) than your runner (HTTP 409). The message names both protocols and your runner’s SDK_VERSION. Two SDK builds on the same protocol are not refused. |
Your code | Run the image tagged with exactly the SDK version your runner installs, everywhere ( Versions and Upgrades). Retrying cannot help. |
executor_unauthorized |
The executor refused your runner’s token (HTTP 401): remoteExecutors({ token }) is not the executor’s EXECUTOR_TOKEN. |
Your code | Set both to the same secret. Retrying cannot help. |
executor_changed |
The conversation’s executor was lost, and the one acquire answered instead differs in its CE.SDK version, its abilities (video), or its asset sources, so the session ends. A different SDK build with the same CE.SDK is not detected. |
Your code | Call again to open a new session on the new executor. If it keeps happening, your pool mixes images, or your plugins register different sources on different executors. |
session_closed |
The design’s engine session was closed, for example by codesign.release(), while the call ran. |
Your code | Call again if the conversation is still going. |
executor_failed |
The executor took the call and could not finish it (HTTP 422): the model’s code ran past the 5-minute limit, after which the executor exits and the next call loads the design on a new one, or the engine failed. | Model | Nothing: the model reads why and tries another way. From your own codesign.edit(), change the code. |
Errors from your own acquire are not wrapped: the tool call rejects with
your error as it is.
Designs and Your Store#
A design’s id is your store’s; designs.read and designs.write are your
functions ( Connect Your Storage). CE.SDK is IMG.LY’s
design engine and editor: the executor runs it, and your own editor may too.
| Kind | When | Who | What to do |
|---|---|---|---|
unknown_design |
The call named no design and there is no default, or designs.read answered undefined for an id that is not the conversation’s default design. design names the id. |
Model | The model is told to pick one of the saved designs or start a new one. From your own call: the id is wrong, or the person may not see it. |
design_changed |
The version the model passed is not the design’s current one, or the design was saved elsewhere while the call ran, so designs.write refused the save. Nothing was kept. |
Model | Nothing: the model looks at the design again and redoes the change. |
design_conflict |
Your own codesign.edit() named a stale version, or your own edit() or load() found the design saved elsewhere while it ran. Nothing was written. design names it. |
Your code | Read what was saved, then call again if you still mean to change it. |
older_saver |
A save would write over a design that a newer CE.SDK saved, the design’s own or, for a copy, the source design’s: an older CE.SDK drops what it does not know. Raised by any call that writes a design, by assertCanSave, and by loadDesign. saver and recorded name both versions, design the design. Nothing was written. |
Your code | Move the executors (and your editor) to that CE.SDK version ( Versions and Upgrades). Retrying cannot help. |
checkpoint_failed |
Saving or reading the design around a call (its checkpoint) failed: your designs.read or designs.write threw, or answered something malformed: a read without content, version, or cesdkVersion, a write without the version it wrote, or a first write that found the id taken. Your message is on the error. If instead the engine could not serialize the design, the model reads it. |
Your code (your store); Model (the engine) | Alert as you would for your own database, and retry once your store answers. A malformed answer is a bug in your store. |
Exports and Billing#
Every file export is charged to your IMG.LY account, and saving the design
(scene, imgly) is free ( Billing).
| Kind | When | Who | What to do |
|---|---|---|---|
export_refused |
The executor would not charge for an export, so nothing was delivered; the message says why, in words for the person. The causes are listed below the table. | Your code | Show the message, or an upgrade prompt, and end the turn. Retrying at once does not help. |
render_failed |
The engine refused to render or encode a block. The message names each image, video, or font that failed to load. | Model | Nothing: the model fixes what the message names. |
no_scene, no_pages |
There is nothing to render: nothing was built or imported yet, or the design has no pages. | Model | Nothing; the model builds the design first. |
not_a_page |
html, wav, or m4a was asked of a block that is not a page; these formats render exactly one page. |
Model | Nothing; the model passes a page. |
not_attached |
A video export of a block the design does not contain. | Model | Nothing; the model passes a block of the design. |
video_unsupported |
A video or audio format (mp4, wav, m4a) was asked of an executor without video encoding. |
Model | Nothing for the model; video is not available on this executor. |
encoder_busy |
The video encoder never became free while the export waited. | Model | Nothing; the model retries later. |
time_out_of_range |
An image of a block at a time past the end of its timeline. |
Model | Nothing; the message gives the duration. |
region_not_on_page, region_outside_page, region_page_unusable |
An image of a region was asked of a block on no page, misses its page, or the page has no usable bounds. |
Model | Nothing; the model picks another region. |
archive_failed |
Saving the .imgly archive failed, rather than write one with files missing; the message names what failed to load. From saveDesign (in ./cesdk-utils): CE.SDK could not save the design. |
Model; your code from saveDesign |
The model fixes what the message names. From saveDesign, keep the editor open and report it. |
pdfx_convert_failed |
The PDF exported, but its conversion to PDF/X, the PDF standard for print, failed. | Model | Nothing for the model; report it if it repeats. |
profile_fetch_failed |
The custom ICC color profile (the file that describes the printer’s colors) for a PDF/X export could not be fetched. | Model | Check the profile’s URL is reachable from the executor. |
An export is refused (export_refused) when:
- the account has no credits left;
- the license key does not include CoDesign;
- the export is over a limit (its longer side, pages, or file size);
- the format is video or audio;
- the billing service answered a 429 without
Retry-After(“reached its export limit for now”); - the export has no valid render id, the id that makes a retried export charged once ( Render ID; the message says “update the SDK”);
- the billing service has not answered once since the executor started (the message names its address);
- your
uploadExportreturned neitherdownloadURLnornote.
Only an outage of the billing service (no answer, a 5xx, a 408, or a 429 with
Retry-After, after the retries) delivers an export uncharged.
Files and Asset Sources#
uploadFile is the function of a source that keeps a new file.
| Kind | When | Who | What to do |
|---|---|---|---|
unsupported_format |
The file is not a design or image this SDK reads: a font, audio, or an unknown type. | Model | Nothing; the model tells the person. |
engine_unsupported_format |
The format is one the SDK knows, but this executor has no importer for it, or cannot export it. | Model | Nothing for the model; that format is not available on this executor. |
not_loadable |
The file looked like a scene string, but the engine would not load it. | Model | Nothing; the file is damaged or not a scene. |
load_failed |
The file could not become a design: the importer failed, a source asset’s file could not be loaded, or other calls kept replacing the engine’s design while it loaded. From loadDesign: CE.SDK could not load the stored design. |
Model; your code from loadDesign |
Retry once; if it repeats, the file or the source’s URL is at fault. |
fetch_failed, http_status |
A file to load from a URL could not be fetched (fetch_failed), or its server answered an error status (http_status). The message names the URL. |
Model; your code from loadDesign |
Check the URL is reachable from where it is fetched, and still valid. |
source_failed |
A source’s uploadFile threw an error that is not a refusal, answered null or a non-object, or kept a file but answered no meta.uri. source names the source. |
Your code | A bug in your plugin module or your API; fix what the message names. To decline a file, return undefined. |
invalid_asset |
A source answered an image asset without a positive meta.width and meta.height, which CE.SDK needs to size a placed image (without them it crops it into a square). source names the source, the message the asset. Raised by a search of your sources and by calls that keep a new image. |
Your code | Keep the size uploadFile is told, and return it from findAssets and fetchAsset ( Image Sizes). |
refused |
A member you wrote threw refusal(text); source names the source when one refused. The SDK also refuses this way when the model names a source that cannot take a new file, or when no source keeps a generated file and there is no design to keep it in. |
Model | Nothing; the model reads text. |
Errors from your own members that are not a CoDesignError keep their
message: from designs.read or designs.write they become
checkpoint_failed, from uploadFile source_failed. From uploadExport
or one of your own tools, the call rejects with your error as it is.
The Model’s Code#
| Kind | When | Who | What to do |
|---|---|---|---|
code_threw |
The model’s code threw. Nothing was stored. | Model | Nothing; the model reads the error and fixes its code. |
invalid_return |
The model’s code ran and its change was stored, but it returned something that is not a tool result part. | Model | Nothing; the model is told not to run it again. |
code_failed |
The code of your own codesign.edit() threw, or returned a value that is not JSON. When it threw, nothing was stored. |
Your code | Fix your code; the message and cause carry the error. |
Codes the Model Reads#
The tools also refuse with codes of their own, which are not
CoDesignErrorKind members. The model reads the words; a tool.call event’s
error.kind carries the code. These codes are for your logs: they can change
in any release, so do not branch on them.
| Code | When |
|---|---|
bad_args |
An argument is missing, of the wrong type, or not allowed, or version is missing or belongs to another design. |
dialect_violation |
The model’s code changes the design with engine.block calls that the design API (engine.design) replaces. Nothing ran. |
unknown_revision |
The design store had nothing under the design’s id when the tool read it. The model checks the id it passed. |
resources_pending |
Fonts or images were still loading when the edit was kept. The model retries. |
scene_file_uri |
The design references a file:// address, which no other machine can load, so the edit was not kept. |
feature_disabled |
The capability is not available here: starting a new design without a designs store, or listing saved designs when designs has no listSourceId. |
engine_unsupported |
The executor cannot do it, such as an image of a moment in a video without video encoding. |
unknown_format |
The model asked for an export in a format the SDK does not know. |
internal_error |
Any other failure the SDK recognizes as its own, such as a design that could not be loaded into the engine. |
The AI Gateway#
Image generation makes images (and other media) through IMG.LY’s AI
gateway, with the credential your gateway.bearer function answers.
| Kind or code | When | Who | What to do |
|---|---|---|---|
generation_refused |
The gateway account is out of credits (insufficient_credits, HTTP 402). Nothing was charged. |
Your code | Show the message, or offer a top-up. Retrying does not help until the account has credits. |
no_credentials |
gateway.bearer answered no credential. |
Model | Make bearer answer one for every request. |
unauthorized |
The gateway rejected the credential (HTTP 401), also after one forceRefresh. |
Model | Check the key bearer answers. |
model_not_found |
The model the agent asked for is not offered to this account. | Model | Nothing; the model lists the catalog and picks another. |
generation_failed |
The generation failed, or the provider rejected the prompt. | Model | Nothing; the model rephrases or retries. |
output_download_failed |
The result was generated, but downloading it failed. The generation may have used credits. | Model | Nothing; the model retries. |
service_error, gateway_error |
The gateway had a temporary problem, or answered a code the SDK does not know (gateway_error). Nothing was charged. |
Model | Nothing; the model retries a moment later. |
The codes other than generation_refused reach your code only as a
tool.call event’s error.kind.
Errors of the Other Entry Points#
@imgly/codesign-sdk/cesdk-utils uses the same CoDesignError and kinds; it
adds none of its own.
addPluginModulesrejects withinvalid_optionswhen a plugin module fails to load or its sources fail the SDK’s checks.loadDesignrejects withinvalid_optionswhen the editor runs another CE.SDK version than the executor (CESDK_VERSION),older_saverwhen a newer CE.SDK saved the design,fetch_failedwhen a{ uri }design cannot be downloaded, andload_failedwhen CE.SDK cannot load it.saveDesignrejects witharchive_failedwhen CE.SDK cannot save the design as a scene string or an archive.
Next Steps#
- API Reference — look up the functions and options these errors come from.
- Troubleshooting — fix what goes wrong when you start, run, or roll out CoDesign.
- Versions and Upgrades — see why
older_saverandexecutor_versionexist.