paperclipai/paperclip · error · Error
Request failed: ${response.status}
Error message
Request failed: ${response.status} What it means
Generic fallback thrown by the internal requestJson() helper in cli/src/client/board-auth.ts when an HTTP response is non-OK (not 2xx) AND the response body is missing, unparseable, or has no string-shaped `error` field. The literal status code is interpolated so the caller sees what the server returned. This helper backs the CLI board-auth flow (create-challenge, poll, /me, revoke), so the failure surfaces during CLI login/token-refresh/revoke, not during normal agent API calls.
Source
Thrown at cli/src/client/board-auth.ts:171
if (init?.body !== undefined && !headers.has("content-type")) {
headers.set("content-type", "application/json");
}
if (!headers.has("accept")) {
headers.set("accept", "application/json");
}
const response = await fetch(url, {
...init,
headers,
});
if (!response.ok) {
const body = await response.json().catch(() => null);
const message =
body && typeof body === "object" && typeof (body as { error?: unknown }).error === "string"
? (body as { error: string }).error
: `Request failed: ${response.status}`;
throw new Error(message);
}
return response.json() as Promise<T>;
}
export async function openUrl(url: string): Promise<boolean> {
const { command, args } =
process.platform === "darwin"
? { command: "open", args: [url] }
: process.platform === "win32"
? { command: "cmd", args: ["/c", "start", "", url] }
: { command: "xdg-open", args: [url] };
return new Promise<boolean>((resolve) => {
let child: ChildProcess;
try {
child = spawn(command, args, { detached: true, stdio: "ignore" });
} catch {View on GitHub (pinned to 67001ec6eb)
Solutions
- Re-run with the correct API base: `paperclipai login --api-base https://your-paperclip.example.com` (no trailing path).
- Check the server is up and the cli-auth routes exist: `curl -i <apiBase>/api/health`.
- If a proxy is in front, confirm it passes JSON bodies through and does not rewrite 4xx/5xx into HTML pages.
- Retry the login; a transient 5xx during deploy resolves once the server is healthy.
Example fix
// before paperclipai login --api-base https://corp.example.com/paperclip/api // (HTML 404 page → "Request failed: 404") // after — point at the API root, no /api suffix paperclipai login --api-base https://corp.example.com
Defensive patterns
Strategy: try-catch
Validate before calling
// Before calling loginBoardCli / requestJson-style helpers, sanity-check the apiBase.
function assertApiBase(apiBase: string): void {
const u = new URL(apiBase); // throws on garbage
if (!u.protocol.startsWith('http')) throw new Error(`apiBase must be http(s): ${apiBase}`);
if (/[?]#/.test(u.href)) throw new Error(`apiBase must not include query/fragment: ${apiBase}`);
} Type guard
function isApiErrorBody(body: unknown): body is { error: string } {
return typeof body === 'object' && body !== null &&
typeof (body as any).error === 'string';
} Try / catch
try {
await loginBoardCli({ apiBase, ... });
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
if (/^Request failed: \d+$/.test(msg)) {
const status = Number(msg.slice('Request failed: '.length));
console.error(`Board auth HTTP ${status} from ${apiBase}; check server health and apiBase.`);
}
throw err;
} Prevention
- Always normalize apiBase (trim, strip trailing slashes) before passing to loginBoardCli.
- Pre-flight GET <apiBase>/api/health before starting an interactive login.
- Do not point the CLI at a proxy that rewrites error responses to HTML.
- Keep CLI and server versions aligned so cli-auth route paths match.
When it happens
Trigger: A board-auth endpoint returns a non-2xx (e.g. 401 on /api/cli-auth/me with a bad/revoked boardApiToken, 404 on a challenge pollPath that does not exist, 500 from the server, or a network proxy returning 502/503) and the body is either empty, not JSON, or JSON without `{ error: string }`. Also triggered if the apiBase is wrong (points at a non-Paperclip host returning HTML, so `.json().catch(()=>null)` yields null).
Common situations: Wrong --api-base (typo, trailing path, pointing at the UI host instead of the API host), server down or restarting during `paperclipai login`, reverse proxy returning an HTML error page (status body not JSON), token revoked between challenge approval and the /api/cli-auth/me call, or a version mismatch where the server's cli-auth routes changed.
Related errors
- CLI auth challenge was cancelled.
- CLI auth challenge expired before approval.
- Request failed with status ${response.status}
- Environment variable ${envName} is empty or not set.
- Challenge secret is required. Pass --token or --token-env.
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/023c67b1bcadb5a6.
Report an issue: GitHub.