odysseus-dev/odysseus · error · Error

data.error

Error message

data.error

What it means

Thrown when POST /api/image/inpaint returns HTTP 200 but the JSON body carries an error field. This pattern means the backend chose to report a failure (typically an upstream AI provider error) inside a successful response instead of a non-2xx status.

Source

Thrown at static/js/editor/ai-inpaint.js:157

      const baseSnap = document.createElement('canvas');
      baseSnap.width = state.imgWidth;
      baseSnap.height = state.imgHeight;
      baseSnap.getContext('2d').drawImage(flatCanvas, 0, 0);
      const res = await fetch('/api/image/inpaint', {
        method: 'POST', credentials: 'same-origin',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify((() => {
          const sel = getSelectedAIEndpoint('inpaint');
          return { image: imageB64, mask: maskB64, prompt, width: state.imgWidth, height: state.imgHeight, strength, feather: 0, _endpoint: sel.endpoint, _model: sel.model };
        })()),
      });
      if (!res.ok) {
        let errDetail = res.statusText;
        try { const errBody = await res.json(); errDetail = errBody.detail || errBody.error || errDetail; } catch {}
        throw new Error(errDetail);
      }
      const data = await res.json();
      if (data.error) throw new Error(data.error);
      if (!data.image) throw new Error('No image returned from inpaint endpoint');
      // Load result as a new layer and clip with the user-drawn mask
      // so only the inpainted region is visible. Cache the
      // unfeathered (AI image + hard mask) on the layer so the live
      // Feather slider can re-derive the alpha on each input event
      // without re-running the model.
      const resultImg = new Image();
      resultImg.onload = () => {
        if (!state.editorOpen) return; // user closed mid-decode
        try {
          saveState('Inpaint result');
          // OpenAI returns at one of its allowed sizes (1024²,
          // 1024×1536, 1536×1024) which often differs from our
          // canvas. Scale to canvas size with smoothing so the
          // inpaint blends in regardless of source dims.
          const shortPrompt = (prompt || '').trim().replace(/\s+/g, ' ').slice(0, 40);
          const layerName = shortPrompt ? `Inpaint: ${shortPrompt}` : 'Inpaint Result';
          const resultLayer = createLayer(layerName, state.imgWidth, state.imgHeight);

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Read the data.error string — it is the upstream provider message and names the real cause
  2. Fix the configuration it points at (valid model name for the endpoint, quota, prompt wording)
  3. Retry after clearing the rate-limit window if the error mentions 429/quota
  4. If you own the backend, return proper 4xx/5xx statuses instead of 200-with-error so monitoring counts these
Defensive patterns

Strategy: validation

Validate before calling

const data = await res.json();
if (data.error) throw new Error(data.error);

Type guard

function isInpaintSuccess(d) { return typeof d === 'object' && d !== null && typeof d.image === 'string' && d.image.length > 0; }

Try / catch

try { const data = await res.json(); if (data.error) throw new Error(data.error); if (!isInpaintSuccess(data)) throw new Error('No image returned from inpaint endpoint'); ... } catch (e) { uiModule.showToast('Inpaint failed: ' + e.message); }

Prevention

When it happens

Trigger: The provider call inside the server fails after the request was accepted: invalid model name for the selected endpoint, provider quota exhausted, content policy rejection, or a provider timeout — the server wraps that as {error: '...'} with 200.

Common situations: Switching _model to one the key does not have access to; provider rate limits hit mid-session; NSFW filter triggering on the prompt/mask region; server code that catches upstream exceptions and returns data.error rather than raising HTTPException.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/cdcb0b7ea2f9b2f8. Report an issue: GitHub.