pbakaus/impeccable · warning

[impeccable] annotation upload failed:

Error message

[impeccable] annotation upload failed:

What it means

When a generate/steer request carries annotations, the captured PNG is POSTed to /annotation?token=...&eventId=... on the live server, and the returned path is attached to the event as screenshotPath. A non-2xx response status or a fetch rejection is logged as 'annotation upload failed:' (with the status code or error); the event is then still sent, just without the annotated image, so the model loses the semantic input but not the request.

Source

Thrown at skill/scripts/live-browser.js:8064

    // Only upload + forward the screenshot when annotations (comments/strokes)
    // are present. Without annotations the image is pure visual anchoring -
    // it biases the model toward the current rendering and works against the
    // three-distinct-directions brief.
    if (blob && hasAnnotations) {
      try {
        const uploadRes = await fetch(
          'http://localhost:' + PORT + '/annotation?token=' + encodeURIComponent(TOKEN) +
          '&eventId=' + encodeURIComponent(basePayload.id),
          { method: 'POST', headers: { 'Content-Type': 'image/png' }, body: blob },
        );
        if (uploadRes.ok) {
          const { path: p } = await uploadRes.json();
          screenshotPath = p;
        } else {
          console.warn('[impeccable] annotation upload failed:', uploadRes.status);
        }
      } catch (err) {
        console.warn('[impeccable] annotation upload failed:', err);
      }
    }
    // Annotated requests must wait for capture + upload because the screenshot
    // is semantic input. Plain requests were already dispatched above.
    if (hasAnnotations) {
      basePayload.clientSentAt = Date.now();
      sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
    }
  }

  //
  // Shader overlay - renders the captured screenshot as a WebGL texture and
  // runs an editorial "ink-wash" fragment shader over it during generation.
  // A single rolling band sweeps top-to-bottom, desaturating + tinting kinpaku
  // and leaving a soft trail. Makes the wait feel like a letterpress scan
  // instead of a dead spinner.
  //

View on GitHub (pinned to f88b2837a7)

Solutions

  1. Check the logged status: 401 → reload the page for a fresh token; 404 → update the live server to a version with /annotation
  2. Resend the annotated request once the server is reachable and the token fresh
  3. Keep annotations modest in size (crop strokes, not full-page) to avoid payload limits

Example fix

// before
if (uploadRes.ok) { /* ... */ } else { console.warn('annotation upload failed:', uploadRes.status); }
// after: one token-refresh retry on auth failure
if (uploadRes.status === 401) { await refreshToken(); uploadRes = await fetch(url, init); }
Defensive patterns

Strategy: retry

Validate before calling

if (!blob?.size) throw new Error('nothing to upload'); // skip upload for empty captures
const uploadUrl = `/annotation?token=${encodeURIComponent(TOKEN)}&eventId=${encodeURIComponent(basePayload.id)}`;

Try / catch

try {
  let res = await fetch(uploadUrl, { method: 'POST', headers: { 'Content-Type': 'image/png' }, body: blob });
  if (res.status === 401) { TOKEN = await refreshToken(); res = await fetch(uploadUrl, { method: 'POST', body: blob }); }
  if (!res.ok) console.warn('annotation upload failed:', res.status);
} catch (err) { console.warn('annotation upload failed:', err); } // always send the event afterwards

Prevention

When it happens

Trigger: Server restarted so the embedded TOKEN is stale (401); an older server build without the /annotation route (404); blob too large or server died mid-upload (network error); wrong PORT after a restart.

Common situations: Server restart between page load and annotation; version skew between injected client and server; uploading a very large annotated screenshot on a constrained machine.

Related errors


AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18). Data as JSON: /api/errors/7248e0bd4c25efe5. Report an issue: GitHub.