paperclipai/paperclip · warning · Error
Claude CLI usage probe ended before rendering usage.
Error message
Claude CLI usage probe ended before rendering usage.
What it means
Thrown by captureClaudeCliUsageText on the success path: execFileAsync completed without error, but cleanTerminalText(output) failed usageOutputLooksComplete (no 'current session' + week/extra + percentage pattern, and no recognized error marker). The probe ran the scripted /usage interaction but the rendered output was incomplete or unrecognizable, so it cannot be trusted as quota data.
Source
Thrown at packages/adapters/claude-local/src/server/quota.ts:451
const claudeCommand = "claude --tools \"\"";
if (process.platform === "darwin") {
return `${feed} | script -q /dev/null ${claudeCommand}`;
}
return `${feed} | script -q -e -f -c ${quoteForShell(claudeCommand)} /dev/null`;
}
export async function captureClaudeCliUsageText(timeoutMs = 12_000): Promise<string> {
const command = buildClaudeCliShellProbeCommand();
try {
const { stdout, stderr } = await execFileAsync("sh", ["-c", command], {
env: createClaudeQuotaEnv(),
timeout: timeoutMs,
maxBuffer: 8 * 1024 * 1024,
});
const output = `${stdout}${stderr}`;
const cleaned = cleanTerminalText(output);
if (usageOutputLooksComplete(cleaned)) return output;
throw new Error("Claude CLI usage probe ended before rendering usage.");
} catch (error) {
const stdout =
typeof error === "object" && error !== null && "stdout" in error && typeof error.stdout === "string"
? error.stdout
: "";
const stderr =
typeof error === "object" && error !== null && "stderr" in error && typeof error.stderr === "string"
? error.stderr
: "";
const output = `${stdout}${stderr}`;
const cleaned = cleanTerminalText(output);
if (usageOutputLooksComplete(cleaned)) return output;
if (usageOutputLooksRelevant(cleaned)) {
throw new Error("Claude CLI usage probe ended before rendering usage.");
}
throw error instanceof Error ? error : new Error(String(error));
}
}View on GitHub (pinned to 67001ec6eb)
Solutions
- Retry the probe — timing-sensitive TUI interactions are flaky; the probe is designed to be re-run.
- Confirm `claude` launches and renders /usage interactively on the same host and user account.
- Ensure the quota probe runs in an environment with a working pty (the `script` binary present, TERM set).
- Prefer the OAuth quota path (fetchClaudeQuota) when available; the CLI probe is a fallback.
Defensive patterns
Strategy: retry
Try / catch
let text;
for (let i = 0; i < 3; i++) {
try {
text = await captureClaudeCliUsageText();
break;
} catch (err) {
if (err.message !== "Claude CLI usage probe ended before rendering usage.") throw err;
}
} Prevention
- Retry the CLI usage probe — its TUI timing is inherently flaky.
- Confirm `claude` renders /usage interactively on the host before relying on the probe.
- Prefer the OAuth quota path and treat the CLI probe as fallback.
When it happens
Trigger: The shell probe (sleep 2; printf '/usage'; sleep 6; ...) ran under `claude --tools ""` via `script`, finished within the 12s timeout, but the terminal output never rendered a complete usage panel — e.g. the /usage keystroke arrived before the TUI was ready, or the panel rendered after the ESC/Ctrl-C sequence.
Common situations: Slow machine where the 2s/6s sleeps in the probe are too short for the Claude TUI to be ready; a Claude CLI version with a different startup/usage render timing; missing TERM/terminal capabilities under the quota env; running under a non-tty where `script` behaves differently.
Related errors
- Choose either --oauth-only or --cli-only, not both.
- Could not parse Claude CLI usage output.
- anthropic usage api returned ${resp.status}
- Choose either --rpc-only or --wham-only, not both.
- Request failed: ${response.status}
AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12).
Data as JSON: /api/errors/0e425418a80add29.
Report an issue: GitHub.