Skip to content

Support JSON 3 - #1687

Merged
olleolleolle merged 1 commit into
lostisland:mainfrom
byroot:json-3.x
Aug 12, 2026
Merged

olleolleolle merged 1 commit into
lostisland:mainfrom
byroot:json-3.x

Conversation

@byroot

@byroot byroot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

In the upcoming json 3.x, JSON.parse and JSON.load take keyword arguments rather than a positional option Hash.

So the options must be splatted.

Thankfully, when splatting on a method that doesn't take keyword arguments, Ruby pass the arguments as positional:

def load(source, options = {})
  p options
end

kwargs = {a: 1, b: 2}
load('null', **kwargs) # => {a: 1, b: 2}

So the change is compatible with both json 2.x and json 3.x

@olleolleolle olleolleolle left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, sounds ace.

@olleolleolle
olleolleolle merged commit b25b1b2 into lostisland:main Aug 12, 2026
9 checks passed
@iMacTia

iMacTia commented Aug 12, 2026

Copy link
Copy Markdown
Member

This is great, thank you for contributing!
There's only one thing I'm not entirely sure about: the decoder is configurable and only defaults to JSON, so people could swap it with any other library (the most popular likely being Oj).

I don't think we have tests that cover this, as it would require the Oj library to be added (which would be fine actually, in the Gemfile), so I was thinking we should at least make sure that one accepts the same change in call structure before shipping a release and risking to break every app using a custom decoder on a minor release.

@byroot

byroot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

If you wish to make changes to this, I suggest instead of taking a method name and arguments, just take either a Proc, or an object that respond to the standard .load method.

@sue445

sue445 commented Sep 12, 2026

Copy link
Copy Markdown

Hi there.

json gem v3.0.0 was recently released.
https://github.com/ruby/json/releases/tag/v3.0.0

However, because this patch has not been released yet, the following error occurs in Faraday::Response::Json.

 Faraday::ParsingError:
   wrong number of arguments (given 2, expected 1)
 # ./vendor/bundle/ruby/3.0.0/gems/json-3.0.2/lib/json/common.rb:296:in `parse'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/response/json.rb:36:in `public_send'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/response/json.rb:36:in `parse'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/response/json.rb:26:in `process_response'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/response/json.rb:19:in `on_complete'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/middleware.rb:57:in `block in call'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/response.rb:46:in `on_complete'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/middleware.rb:56:in `call'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/middleware.rb:56:in `call'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/rack_builder.rb:158:in `build_response'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/connection.rb:452:in `run_request'
 # ./vendor/bundle/ruby/3.0.0/gems/faraday-2.14.3/lib/faraday/connection.rb:200:in `get'
 # ./spec/faraday/mashify/integration_spec.rb:16:in `block (2 levels) in <top (required)>'
 # ./vendor/bundle/ruby/3.0.0/gems/webmock-3.26.4/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # ArgumentError:
 #   wrong number of arguments (given 2, expected 1)
 #   ./vendor/bundle/ruby/3.0.0/gems/json-3.0.2/lib/json/common.rb:296:in `parse'

Do you have any plans to release a new version that includes this patch?

@dblock

dblock commented Sep 12, 2026

Copy link
Copy Markdown

This fix isn't in a release yet (latest is v2.14.3). Worked around it in the meantime with a custom middleware: dblock/strava-ruby-client#115. Looking forward to a new Faraday release with this included!

(Comment posted by an AI on behalf of @dblock.)

@crevete

crevete commented Sep 15, 2026

Copy link
Copy Markdown

@olleolleolle When the next release will be cut please?

@sue445

sue445 commented Sep 16, 2026

Copy link
Copy Markdown

@crevete It looks like v2.14.4 has already been released.
https://github.com/lostisland/faraday/releases/tag/v2.14.4

@olleolleolle Thanks for the release!

@dblock

dblock commented Sep 17, 2026

Copy link
Copy Markdown

Verified in dblock/strava-ruby-client#115: Faraday v2.14.4 fixes the json 3 compatibility issue for us. We now require Faraday >= 2.14.4, use the built-in :json middleware again, and our test suite passes against both JSON 2 and JSON 3.

Thanks for the fix and release!

Posted by an AI on behalf of @dblock.

G-Rath added a commit to ackama/rails-template that referenced this pull request Sep 17, 2026
While @byroot has done great work in ensuring the ecosystem is
compatible with `json` v3, it seems like a few gems still need to
catch-up - notably, both
[Rails](rails/rails#58601) and
[Faraday](lostisland/faraday#1687) have not yet
released their compatibility fixes.

Interestingly only our `devise` variant actually fails, but in an
internal app with 100% coverage I only needed to patch Rails & Faraday
to have everything seemingly working and `devise` does not seem to use
JSON directly itself.

I think overall it's better to play it safe and pin ourselves to JSON v2
at least until Rails has released their patch
simonx1 added a commit to simonx1/ruby-mcp-client that referenced this pull request Sep 21, 2026
…251)

Unblocks #248 (Dependabot's rubocop 1.90.0 → 1.91.0 bump).

## What breaks in #248

The rubocop bump re-resolves `json` from 2.21.2 to 3.0.2, and json 3.0
makes every parser option a keyword argument. faraday 2.14.3's JSON
response middleware still passes them as a positional hash, so
`JSON.parse(body, {})` raises:

```
ArgumentError: wrong number of arguments (given 2, expected 1)
  json-3.0.2/lib/json/common.rb:296:in 'JSON.parse'
  faraday-2.14.3/lib/faraday/response/json.rb:36:in 'Faraday::Response::Json#parse'
```

Every spec that mounts a host's `conn.response :json` middleware fails
the same way — 29 failures on both the Ruby 4.0.6 and the Ruby 3.3 job.
Nothing in `lib/` calls `JSON.parse`/`JSON.generate` with positional
options; the library itself is fine on json 3.

## The fix

faraday 2.14.4 (released 2026-09-15, the day after #248's CI run) ships
lostisland/faraday#1687 "Support JSON 3". `bundle update faraday
--conservative` moves faraday alone — the entire diff is:

```diff
-    faraday (2.14.3)
+    faraday (2.14.4)
```

The gemspec's `faraday ~> 2.0` already admits it, so nothing changes
for gem consumers.

## Verification

- On #248's branch (json 3.0.2) with faraday bumped to 2.14.4: the 26
  middleware examples pass, and the full suite is 4397 examples,
  0 failures on Ruby 4.0.6.
- On this branch (json 2.21.2): rubocop clean across 232 files; full
  suite 4398 examples with one failure, the pattern-timeout spec that
  #247 also trips — it is timing-dependent and unrelated to faraday
  (this run shared the CPU with a second suite). Its fix is the sibling
  PR "test: make the pattern-timeout spec exhaust its budget in the
  match, not the preflight".
- `bundle check` satisfied.

## After merging

Comment `@dependabot rebase` on #248 so it re-resolves on top of this
lockfile.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.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.

7 participants