pbakaus/impeccable · error
Unauthorized
Error message
Unauthorized
What it means
GET /manual-edit-stash on the impeccable live server returns the pending manual-edit buffer (count, perPage, entries filtered by pageUrl). It is gated by a per-server-instance token: the token query parameter must string-equal the server's current token (generated at startup and recorded in its server.json). A bare writeHead(401) 'Unauthorized' is returned on mismatch or omission.
Source
Thrown at skill/scripts/live/manual-edit-routes.mjs:80
}
const { totalCount, perPage } = countPendingByPage(projectCwd());
const pendingCount = perPage[msg.pageUrl] || 0;
recordManualEditActivity('manual_edit_stashed', {
id: msg.id,
pageUrl: msg.pageUrl,
opCount: msg.ops.length,
pendingCount,
totalCount,
hintedFileCount: new Set((msg.ops || []).map((op) => summarizeManualLogFile(op.sourceHint?.file, projectCwd())).filter(Boolean)).size,
});
sendJson(res, 200, { ok: true, pendingCount, totalCount, perPage });
});
return true;
}
if (p === '/manual-edit-stash' && req.method === 'GET') {
const token = url.searchParams.get('token');
if (token !== getToken()) { res.writeHead(401); res.end('Unauthorized'); return true; }
const pageUrl = url.searchParams.get('pageUrl') || '';
const { totalCount, perPage } = countPendingByPage(projectCwd());
const buffer = readManualEditsBuffer(projectCwd());
const entriesForPage = pageUrl ? buffer.entries.filter((e) => e.pageUrl === pageUrl) : buffer.entries;
sendJson(res, 200, {
count: pageUrl ? (perPage[pageUrl] || 0) : totalCount,
totalCount,
perPage,
entries: entriesForPage,
});
return true;
}
if (p === '/manual-edit-commit' && req.method === 'POST') {
const token = url.searchParams.get('token');
if (token !== getToken()) { res.writeHead(401); res.end('Unauthorized'); return true; }
const pageUrl = url.searchParams.get('pageUrl');
const asyncMode = /^(1|true|yes)$/i.test(url.searchParams.get('async') || '');View on GitHub (pinned to f88b2837a7)
Solutions
- Read the current token from the live server's output/session (server.json records port + token) and re-issue the request with ?token=
- Reload the target page after any server restart so the injected client re-fetches live.js with the fresh token
- Confirm the port matches the running server instance
Example fix
# before curl 'http://localhost:4173/manual-edit-stash?pageUrl=/' # after curl "http://localhost:4173/manual-edit-stash?token=$TOKEN&pageUrl=/"
Defensive patterns
Strategy: retry
Validate before calling
// Validate request preconditions before polling
const token = readTokenFromSession(); // server.json: port + token
if (!token) throw new Error('no live-server token — is the server running?');
const url = `http://localhost:${PORT}/manual-edit-stash?token=${encodeURIComponent(token)}`; Try / catch
let res = await fetch(url);
if (res.status === 401) {
TOKEN = readTokenFromSession(); // token rotated after restart
res = await fetch(urlWithNewToken); // single retry
} Prevention
- Read port + token from the server session file at call time, never hardcode
- After restarting the live server, reload the target page before scripting against its routes
- A 401 means token mismatch, not server death — refresh the token rather than rebooting everything
When it happens
Trigger: Calling /manual-edit-stash without ?token=; using a token captured from a previous server run after the server restarted (tokens rotate per instance); hitting the wrong port so a different server's token is compared.
Common situations: Server restarted while an old browser tab kept polling with the embedded old TOKEN; curl scripts with a hardcoded token; page loaded from cache after server death and rebirth.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of pbakaus/impeccable@f88b2837a7 (2026-08-18).
Data as JSON: /api/errors/fe3c4a78f71f27e7.
Report an issue: GitHub.