Skip to content

fix(anthropic): tolerate usage API metadata fields (limits/spend)#90

Open
yesme wants to merge 1 commit into
onllm-dev:mainfrom
yesme:fix/anthropic-usage-metadata-fields
Open

fix(anthropic): tolerate usage API metadata fields (limits/spend)#90
yesme wants to merge 1 commit into
onllm-dev:mainfrom
yesme:fix/anthropic-usage-metadata-fields

Conversation

@yesme

@yesme yesme commented Jul 14, 2026

Copy link
Copy Markdown

Summary

Fixes Anthropic OAuth usage polling when /api/oauth/usage includes top-level metadata fields such as limits (array), spend (unrelated object), and booleans.

This is an enhanced take on #84 (same root cause / same minimal approach), with two robustness improvements observed against a live mid-2026 usage payload.

Fixes #82.
Related: #84.

Root cause

AnthropicQuotaResponse was map[string]*AnthropicQuotaEntry. Anthropic now returns companion top-level fields; limits is an array, so the whole decode fails with:

json: cannot unmarshal array into Go value of type api.AnthropicQuotaEntry

Auth/token refresh is fine — only response-schema decoding breaks.

Changes

  • Custom UnmarshalJSON for AnthropicQuotaResponse
  • Keeps quota objects and null inactive buckets
  • Ignores non-object metadata (limits[], booleans, …)
  • Enhancement over Handle Anthropic usage metadata arrays #84: also drops non-quota objects that share no AnthropicQuotaEntry fields (e.g. spend), instead of leaving empty entries in the map
  • Enhancement over Handle Anthropic usage metadata arrays #84: per-key decode errors are skipped so one bad companion/experimental object cannot take down the entire poll
  • Client + unit regression tests covering the live-ish response shape

Test plan

  • go test ./internal/api -count=1 -run 'Anthropic|ParseAnthropic'
  • Branch is based on onllm-dev/onWatch@main and contains only this fix (single commit)
  • CI green on this PR
go test ./internal/api -count=1 -run 'Anthropic|ParseAnthropic'

Anthropic /api/oauth/usage now returns top-level companion fields such as
limits (array), spend (unrelated object), and booleans alongside quota
buckets. Decoding the whole payload as map[string]*AnthropicQuotaEntry
failed with:

  cannot unmarshal array into Go value of type api.AnthropicQuotaEntry

Add a custom UnmarshalJSON that keeps null/object quota entries and
ignores non-quota metadata. Enhances onllm-dev#84 by also dropping non-quota
objects (spend) and skipping per-key decode errors so one bad companion
field cannot take down the entire Anthropic poll.

Fixes onllm-dev#82.
Related: onllm-dev#84.
hiyukoim added a commit to hiyukoim/onWatch that referenced this pull request Jul 20, 2026
Anthropic's /api/oauth/usage now returns companion top-level fields
(limits array, spend object, booleans) that broke decoding into
map[string]*AnthropicQuotaEntry, taking down all Anthropic quota
polling and leaving the dashboard empty even after reload.

Port upstream fix from onllm-dev#90 (confirmed against live
payloads in onllm-dev#82): custom UnmarshalJSON keeps quota-shaped objects,
preserves null inactive buckets, and ignores non-quota metadata.
Also treat a root-level empty array body as zero quotas (onllm-dev#87).

Co-authored-by: Yuko <hiyukoim@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anthropic quota fetch broken — /api/oauth/usage now returns an array for a bucket value (cannot unmarshal array into AnthropicQuotaEntry)

1 participant