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

  1. Read the current token from the live server's output/session (server.json records port + token) and re-issue the request with ?token=
  2. Reload the target page after any server restart so the injected client re-fetches live.js with the fresh token
  3. 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

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

Related errors


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