Skip to content

fix(claude): read nested JSON objects regardless of key order - #24

Merged
hyperb1iss merged 1 commit into
mainfrom
nova/claude-json-key-order
Sep 14, 2026
Merged

hyperb1iss merged 1 commit into
mainfrom
nova/claude-json-key-order

Conversation

@hyperb1iss

Copy link
Copy Markdown
Owner

πŸ› What broke

CI on main failed in the extras spec, on the stable Neovim job only: renders the Claude Code status line from a payload reported missing 31% for every variant while v0.10.4 and nightly passed. The same commit had passed on its PR run minutes earlier.

πŸ” Why

The status line parses its JSON with bash regex helpers. json_obj captured a nested object up to its first closing brace, assuming every object lists its scalars before any object of its own. The spec encodes its payload with vim.json.encode, whose key order varies by build, and on the stable runner context_window came out with current_usage ahead of used_percentage. The percentage landed outside the capture, the token-sum fallback rounded 61500/200000 down to 30%, and the assertion on 31% failed.

Claude Code's real payload carries the same risk, since nothing guarantees its key order either.

πŸ› οΈ The fix

json_obj now matches one level of nesting and strips the inner objects from the body before any scalar lookup, so a key that recurs across objects (used_percentage lives in both context_window and the rate limit objects) still resolves against the right parent. All ten call sites read from the top-level payload, so none of them depended on inner objects surviving. The five generated scripts under extras/claude/ are rebuilt from the template.

βœ… Verification

  • Reproduced locally by piping a payload with current_usage first: 30% before the fix, 31% after.
  • make test green, and the status line spec rerun twelve times in a loop with no failures.
  • bash -n on all five generated scripts, shellcheck unchanged from before.
  • Lint and the prettier format gate pass with the Makefile's globs.

πŸ€– Generated with Claude Code

https://claude.ai/code/session_01WAKpAw1biNtpxi3VEb37Nw

The status line's json_obj captured a nested object only up to its first
closing brace, on the assumption that every object lists its scalars
ahead of any object of its own. Key order is not guaranteed: the extras
spec encodes its payload with vim.json.encode, whose order varies by
build, and on one CI runner context_window came out with current_usage
ahead of used_percentage. The percentage then fell outside the capture,
the token-sum fallback rounded 61500/200000 down to 30%, and the spec
failed on the stable job alone while v0.10.4 and nightly passed.

The match now spans one level of nesting and cuts the inner objects out
of the body before any scalar lookup, so a recurring key such as
used_percentage still resolves against the right object. Every caller
reads from the top-level payload, so nothing depended on the inner
objects surviving. Generated scripts rebuilt for all five variants.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WAKpAw1biNtpxi3VEb37Nw
@hyperb1iss
hyperb1iss merged commit f0be29b into main Sep 14, 2026
8 checks passed
@hyperb1iss
hyperb1iss deleted the nova/claude-json-key-order branch September 14, 2026 00:12
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.

1 participant