Options hiding inside JSON now fail loudly - #47
Merged
Merged
Conversation
nz
enabled auto-merge
August 11, 2026 00:20
lutzcc1
previously approved these changes
Aug 11, 2026
The serialization guard only held at the top level. ActiveSupport's
Hash#as_json and Array#as_json recurse through their members with
as_json, never to_json, so a nested Option reached Object#as_json and
serialized as its instance variables: {a: Some(5)}.to_json produced
{"a":{"value":5}} with no error, and a None became {}.
Define as_json on Option::Any and Result::Any to raise SerializeError
alongside to_s and to_json. Almost every real serialization path goes
through a Hash or an Array, so this is where the guard earns its keep.
h3h
approved these changes
Aug 12, 2026
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.
Fixes #43.
An Option at the top level already refuses to turn into JSON: it raises an error. But an Option hiding inside a hash or an array slipped through, and came out as strange JSON like
{"value":5}. A missing value came out as{}. No error, no warning. Now it raises the same loud error no matter how deeply it is buried.Detail
as_jsononOption::AnyandResult::AnyraisesSerializeErrorwith the same messages asto_s/to_json. ActiveSupport'sHash#as_json/Array#as_jsonrecurse viaas_json, neverto_json, which is how the existing guard was bypassed.Ok(5).as_json => {"value"=>5}), not mentioned in the issue; fixed alongside.as_jsonwithout ActiveSupport loaded is harmless, so it is unconditional.Covered in
test/rails_test.rb(hash and array nesting, Option and Result) rather than doctests, since doctests run without ActiveSupport.