fix(api): tolerate null resets_at for unused usage windows#18
Open
jeanfw wants to merge 1 commit into
Open
Conversation
The Claude API legitimately returns 'resets_at: null' for usage windows with no consumption yet (e.g. a client account that hasn't been used today). The mapper was rejecting these responses, surfacing 'Server response missing critical field: fiveHour.resetsAt' in the popover and blocking refresh entirely. Now a null reset_at falls back to now plus the window duration (matching the existing behaviour for sonnet usage). A present-but-malformed date string is still treated as a hard error. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Claude API legitimately returns
resets_at: nullon usage windows that have no consumption yet — typically when an account hasn't been used in the last 5 hours (so there's no active session window to reset). Today the mapper rejects these responses and surfaces:…which blocks refresh entirely for that account. The popover shows the orange
Server returned invalid responsebanner and the user has no recourse short of using Claude on that account to force the API to populate the field again.The fix
UsageAPIResponse.toDomain()now treats a nullresets_atthe same way it already treats a nullsevenDaySonnet.resets_at: it falls back tonow + window duration(5 hours for the session window, 7 days for the weekly window). A present-but-malformed date string is still treated as a hard error, since that's a real protocol violation.Logic is factored into a small
parseResetDate(from:field:formatter:fallback:)helper so all three windows use the same path.Test plan
test_usageFetch_withMissingResetAt_fillsInFallbackWindowcovers the new behaviour — nullresets_aton the session window decodes to a future date roughly one session-window from now.test_usageFetch_withMalformedResetAt_surfacesInvalidResponseensures the strict path is still wired up — a non-ISO string surfacesAppError.networkError(.invalidResponse).test_usageFetch_withInvalidPayload_surfacesInvalidResponsewas renamed to make the intent unambiguous after this change).🤖 Generated with Claude Code