Skip to navigation

AI Image Editor error handling

Beta

Two things happen when a generation or edit fails. The editor handles the user: it shows a localized message in place and stays usable, with no wiring needed on your side. Your app gets the uc:error event for everything the built-in UI can’t know about: logging, metrics, or reacting to specific failures.

const editor = document.querySelector('uc-ai-image-editor');
editor.addEventListener('uc:error', (e) => {
const error = e.detail.error; // always an AiImageEditorError
console.warn(`generation failed: ${error.code}`, error);
});

The event bubbles and crosses shadow DOM boundaries (composed), so a listener on a container, or on document, works too.

The error object

detail.error is always an AiImageEditorError. Whatever actually went wrong (a platform rejection, a network failure, even a custom provider throwing a string) is normalized into it:

FieldTypeWhat it tells you
codeAiImageEditorErrorCodeWhat failed: one of the known codes, or any other string (backend-minted, or frontend-originated like the React wrapper’s engine_load_failed). 'unknown' when the failure carried no code (e.g. a network error).
messagestringThe raw, untranslated failure text, for logs rather than for users (show localized messages instead).
sourcestring | undefinedWhich stage of a job reported the failure, when the backend says (e.g. 'ai_gateway'). Values are backend-defined, so treat them as log enrichment rather than something to branch on.
causeunknownThe original thrown value, untouched: the underlying Error, or whatever a custom provider threw.

Error codes

code is the field to branch on:

import type { AiImageEditorError } from '@uploadcare/ai-image-editor';
function report(error: AiImageEditorError) {
switch (error.code) {
case 'content_moderated':
// the prompt was blocked — nothing to retry
break;
case 'provider_unavailable':
case 'generation_timeout':
// transient — worth offering a retry
break;
default:
console.error('ai-image-editor failed:', error.code, error.message);
}
}

Every failure is also logged to the console ([uc-ai-image-editor], with the code and the error object), so a code you haven’t wired up still shows up while debugging.

The known codes come in four families:

FamilyExample codesWhat went wrong
Platform validationinvalid_source, canvas_too_large, derivative_disabledBad input or project setup
AI gatewaycontent_moderated, provider_unavailable, generation_timeoutThe generation itself
Auth tokenAccessTokenExpiredError, ScopeForbiddenError, OperationsLimitExceededError, AccessTokenInvalidError, auth_token_failedSigned AI image generation or signed uploads refused the token, or your authToken function threw (auth_token_failed)
Upload pipelineDownloadFileHTTPClientError and friendsSaving the result

PascalCase codes come from Upload API. snake_case codes come from the editor.

Your handler gets every code. The on-screen message is less specific: codes the user can act on get their own wording, and the rest, including every token failure, share a generic one. The localization guide lists each message.

AiImageEditorErrorCode is deliberately open: the known codes are typed as literals (you get autocomplete for them), but the backend can introduce new ones at any time, so any other string flows through rather than breaking. Don’t treat the union as closed; keep a default branch.

When your auth token function fails

A throw from an authToken function never reaches the backend, so there is no server code to report. It arrives as code: 'auth_token_failed', with the AuthTokenResolverError on cause and whatever your function threw on cause.cause:

editor.addEventListener('uc:error', (e) => {
if (e.detail.error.code === 'auth_token_failed') {
// Your token endpoint failed; nothing was sent to Uploadcare.
console.warn('could not get a token', e.detail.error.cause?.cause);
}
});

To tell a lost session from a dead endpoint, include your endpoint’s HTTP status in what the function throws, then check it on cause.cause: a 401 means the user has to sign in again, while a 500 or a network error is worth retrying.

Inside File Uploader you don’t set the token: the editor uses the uploader’s token function and its cache. You can still get this error there. If that function throws while a generation is running, it surfaces as auth_token_failed on the editor’s uc:error, so listen for it either way.

Enabling AI Image Editor

derivative_disabled means AI generation isn’t enabled for your project. The visitor can’t act on it, so the editor only tells them “Image generation is disabled for this site.” Watch for the code on uc:error or in the console instead. During the public beta, AI Image Editor is available on all paid Uploadcare plans. Upgrade your plan if you’re on a free one, or contact support if you hit this code on a paid account.

React

The React wrapper delivers the same object to onError:

<AiImageEditor
pubkey="YOUR_PUBLIC_KEY"
onError={(error) => console.warn(error.code, error.cause)}
/>

One React-specific case: if the lazily-loaded editor engine itself fails to load (e.g. a chunk request dies on a flaky connection), onError receives an AiImageEditorError with code: 'engine_load_failed' and the fallback stays rendered. That code is frontend-originated, so it never appears in the backend families above.

Customizing the in-editor messages

The message the editor shows for a code is a locale string, overridable per-code without touching your event handling:

editor.localeDefinitionOverride = {
en: { 'ai-image-editor-error-content_moderated': 'That prompt isn’t allowed here.' },
};

Each code has its own key, so overriding one changes that code alone: several share the same default text, and changing one of those leaves the others as they were. A code with no key (one this version has never heard of) falls back to the generic ai-image-editor-error. See Localization for the mechanics and the full key list.

Server-side code

instanceof AiImageEditorError works in server code too. Import the class from the side-effect-free errors entry, which is safe where the main entry is not (the main entry registers custom elements):

import { AiImageEditorError } from '@uploadcare/ai-image-editor/errors';
if (err instanceof AiImageEditorError && err.code === 'derivative_disabled') {
// e.g. surface a setup hint in your server logs
}

What doesn’t fire uc:error

  • Cancellations. Closing the editor fires uc:cancel; superseding or aborting an in-flight generation (Start over, unmount) is swallowed silently, since an abort is a user action rather than a failure.
  • Image display failures. If a result generated fine but its image fails to load into the canvas, that surfaces as a separate uc:image-error event (detail.url names the failing URL). The generation itself didn’t fail.