Skip to content

Claude Code usage limits report unauthenticated: macOS Keychain blob is hex JSON #2928

Description

@Guitaraholic

Summary

Settings → Usage limits reports Claude Code as unauthenticated on macOS even when claude is logged in and ~/.claude/.credentials.json is valid JSON. The host reads the Keychain item Claude Code-credentials first, treats the blob as UTF-8 JSON, fails, and never falls through to the credentials file.

Versions and environment

  • bb from source at get-bb/bb main (eeaaa3e8db7b3aeb3c4ab46873816c84cb6ea513)
  • macOS, Claude Code 2.1.x (2.1.257 observed)
  • Isolated desktop instance; Claude Code logged in via OAuth (Max)

Steps to reproduce

  1. On macOS, log in with Claude Code 2.1.x so Keychain has Claude Code-credentials.
  2. Confirm the Keychain secret is hex (security find-generic-password -s "Claude Code-credentials" -w starts with 7b, which is {).
  3. Confirm ~/.claude/.credentials.json is valid JSON with claudeAiOauth.
  4. Open bb → Settings → Usage limits for that host, or GET /api/v1/system/usage-limits.

Did not reproduce the unauthenticated status after decoding the Keychain blob as hex then JSON, then falling back to ~/.claude/.credentials.json.

Expected vs actual

Actual (host provider.usage for claude-code):

status: "unauthenticated"

Settings shows no Claude session/weekly/Fable windows. The Usage plugin can only render that empty/error state.

Expected: status: "ok" with the same 5-hour / weekly / model-scoped windows the Claude Code CLI shows.

Evidence

plugins/provider-claude-code/src/bridge/provider-maintenance.ts on main parses the Keychain stdout as UTF-8 JSON:

const parsed = claudeCredentialsSchema.safeParse(JSON.parse(raw));

Claude Code 2.1.x stores that Keychain password as hex-encoded JSON (7b… = {). JSON.parse throws, the file fallback is skipped because the Keychain read succeeded with a non-empty string.

A unit fixture of hex({"claudeAiOauth":{…}}) fails JSON.parse and succeeds after Buffer.from(raw, "hex").toString("utf8").

What you ruled out

  • Not empty windows from a stale User-Agent (claude-code/2.1.0) or kind === "weekly_scoped" filtering: the live API never ran because status was unauthenticated.
  • Not the community Usage plugin: it only renders GET /api/v1/system/usage-limits.
  • Not a missing ~/.claude/.credentials.json: the file was valid; the Keychain path ran first and failed closed.
  • Searched get-bb/bb issues for hex / keychain / unauthenticated usage-limits; no existing report of this parse.

Suggested priority and effort (optional)

High for anyone on Claude Code 2.1.x on macOS using Usage limits; workaround is none in Settings. Fix is a few lines: decode hex JSON, then fall back to the credentials file. Effort Low.

AGENT GENERATED

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-reproBug reproduced independently; see linked reportprovider-claude-codeBuilt-in plugin: provider-claude-codeprovidersCross-provider bridges, models, login

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions