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
- Check the logged status: 401 → reload the page for a fresh token; 404 → update the live server to a version with /annotation
- Resend the annotated request once the server is reachable and the token fresh
- 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
- Refresh the token after server restarts before uploading
- Keep annotated screenshots compact (crop to the element)
- Log the numeric status — 401 vs 404 vs network tells you exactly which fix applies
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
- Unauthorized
- [impeccable] failed to fetch pending count:
- [impeccable] Svelte ancestor crop capture failed, falling ba
- [impeccable] capture failed, proceeding without screenshot:
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/7248e0bd4c25efe5.
Report an issue: GitHub.