Skip to content

fix(deps): pin json < 3 (activesupport 8.1.3 is not json-3 compatible) - #235

Merged
ursm merged 1 commit into
mainfrom
pin-json
Sep 7, 2026
Merged

ursm merged 1 commit into
mainfrom
pin-json

Conversation

@ursm

@ursm ursm commented Sep 7, 2026

Copy link
Copy Markdown
Owner

The failure

Every branch's CI (main included) went red on the self-contained Action Cable spec:

ArgumentError (wrong number of arguments (given 2, expected 1))
  json-3.0.0/lib/json/common.rb:296  in 'JSON.parse'
  activesupport-8.1.3/.../json/decoding.rb:25  in 'ActiveSupport::JSON.decode'
  actioncable-8.1.3/.../connection/base.rb:196  in '#decode'

Root cause

json 3.0.0 dropped the 2nd positional argument to JSON.parse (options are keyword-only now), but activesupport 8.1.3 still calls JSON.parse(json, options). Action Cable's Connection::Base#decode runs that on every incoming websocket frame, so under json 3.0.0 it raises — the subscribe command is never processed and the spec's connected() callback never fires (a silent, timing-shaped failure).

Gemfile.lock is gitignored, so CI re-resolved to json 3.0.0 the day it shipped — reddening the whole matrix on a dependency change unrelated to any code. Confirmed with a local A/B: json 2.19.5/2.21.2 pass, json 3.0.0 fails.

Fix

Pin json < 3 for dev/CI, next to the actioncable dep that surfaces it, mirroring the existing flatware pin's rationale (an unconstrained major hitting CI unbisectably). The gemspec stays unconstrained — csim's own JSON usage is json-3-clean (the other ~11k specs pass on 3.0.0); only the Rails test stack isn't ready. Drop the pin once activesupport ships a json-3 fix.

Note

This unblocks main and the two open PRs (#233 perf gate, #234 native removal), whose red CI was entirely this dependency issue, not their own changes.

🤖 Generated with Claude Code

json 3.0.0 removed the 2nd POSITIONAL argument to `JSON.parse` (options
are keyword-only now), but activesupport 8.1.3 still calls
`JSON.parse(json, options)` in `ActiveSupport::JSON.decode`. Action
Cable's `Connection::Base#decode` runs that on every incoming frame, so
under json 3.0.0 it raises `wrong number of arguments (given 2, expected
1)` — the subscribe is never processed and the self-contained cable spec's
`connected()` callback never fires. The gitignored Gemfile.lock let CI
re-resolve to json 3.0.0 the day it shipped, reddening the whole matrix
on a dependency change unrelated to any code (main included).

Pin json to < 3 for dev/CI, next to the actioncable dep that surfaces it
and mirroring the existing flatware pin's rationale. The gemspec stays
unconstrained: csim's own JSON usage is json-3-clean (the other 11k specs
pass on 3.0.0); only the Rails test stack isn't ready. Drop the pin once
activesupport ships a json-3 fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DYNGgfDAteLVXeaMaDmjJ4
@ursm
ursm merged commit 8b69c6a into main Sep 7, 2026
5 checks passed
@ursm
ursm deleted the pin-json branch September 7, 2026 10:34
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