{"record":{"id":"0e425418a80add29","repo":"paperclipai/paperclip","slug":"claude-cli-usage-probe-ended-before-rendering-usag","errorCode":null,"errorMessage":"Claude CLI usage probe ended before rendering usage.","messagePattern":"Claude CLI usage probe ended before rendering usage\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/adapters/claude-local/src/server/quota.ts","lineNumber":451,"sourceCode":"  const claudeCommand = \"claude --tools \\\"\\\"\";\n  if (process.platform === \"darwin\") {\n    return `${feed} | script -q /dev/null ${claudeCommand}`;\n  }\n  return `${feed} | script -q -e -f -c ${quoteForShell(claudeCommand)} /dev/null`;\n}\n\nexport async function captureClaudeCliUsageText(timeoutMs = 12_000): Promise<string> {\n  const command = buildClaudeCliShellProbeCommand();\n  try {\n    const { stdout, stderr } = await execFileAsync(\"sh\", [\"-c\", command], {\n      env: createClaudeQuotaEnv(),\n      timeout: timeoutMs,\n      maxBuffer: 8 * 1024 * 1024,\n    });\n    const output = `${stdout}${stderr}`;\n    const cleaned = cleanTerminalText(output);\n    if (usageOutputLooksComplete(cleaned)) return output;\n    throw new Error(\"Claude CLI usage probe ended before rendering usage.\");\n  } catch (error) {\n    const stdout =\n      typeof error === \"object\" && error !== null && \"stdout\" in error && typeof error.stdout === \"string\"\n        ? error.stdout\n        : \"\";\n    const stderr =\n      typeof error === \"object\" && error !== null && \"stderr\" in error && typeof error.stderr === \"string\"\n        ? error.stderr\n        : \"\";\n    const output = `${stdout}${stderr}`;\n    const cleaned = cleanTerminalText(output);\n    if (usageOutputLooksComplete(cleaned)) return output;\n    if (usageOutputLooksRelevant(cleaned)) {\n      throw new Error(\"Claude CLI usage probe ended before rendering usage.\");\n    }\n    throw error instanceof Error ? error : new Error(String(error));\n  }\n}","sourceCodeStart":433,"sourceCodeEnd":469,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapters/claude-local/src/server/quota.ts#L433-L469","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let text;\nfor (let i = 0; i < 3; i++) {\n  try {\n    text = await captureClaudeCliUsageText();\n    break;\n  } catch (err) {\n    if (err.message !== \"Claude CLI usage probe ended before rendering usage.\") throw err;\n  }\n}","preventionTips":["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."],"tags":["claude","cli","quota","terminal","timing","probe"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}