Search Docs
Loading...
Skip to content

Errors

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: true and 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’s cause.

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:

  • prepareCoDesign has no gateway, an uploadExport that is not a function, a plugins entry that is not { module, options? }, or a catalog entry (googleFonts, cesdkDefaults, or cesdkDemo) with wrong options.
  • When a session opens, one of your sources fails the SDK’s checks, or designs.listSourceId names a source no plugin registered (source names it).
  • In your own codesign.edit(), args is not JSON, or code is neither a string nor a function expression.
  • assertCanSave was 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 uploadExport returned neither downloadURL nor note.

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.

  • addPluginModules rejects with invalid_options when a plugin module fails to load or its sources fail the SDK’s checks.
  • loadDesign rejects with invalid_options when the editor runs another CE.SDK version than the executor (CESDK_VERSION), older_saver when a newer CE.SDK saved the design, fetch_failed when a { uri } design cannot be downloaded, and load_failed when CE.SDK cannot load it.
  • saveDesign rejects with archive_failed when CE.SDK cannot save the design as a scene string or an archive.

Next Steps#