Skip to content

Fix JSON decoder exception when referencing different message’s enum - #59

Merged
andersfugmann merged 1 commit into
andersfugmann:mainfrom
mbickers:fix-json-enum-initialization
Sep 26, 2026
Merged

andersfugmann merged 1 commit into
andersfugmann:mainfrom
mbickers:fix-json-enum-initialization

Conversation

@mbickers

@mbickers mbickers commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Defer JSON enum mapping initialization until first use to avoid an exception when a message references another message’s nested enum.

I added a regression test. Without fix, test fails with

Fatal error: exception File "test/json_enum_initialization.ml", line 126, characters 6-12: Undefined recursive module
Raised at CamlinternalMod.init_mod_field.fn in file "camlinternalMod.ml", line 30, characters 11-49
Called from Ocaml_protoc_plugin__Deserialize_json.map_enum_json in file "src/ocaml_protoc_plugin/deserialize_json.ml", line 197, characters 4-16
Called from Ocaml_protoc_plugin__Deserialize_json.read_value in file "src/ocaml_protoc_plugin/deserialize_json.ml", line 312, characters 25-52
Called from Ocaml_protoc_plugin__Deserialize_json.read in file "src/ocaml_protoc_plugin/deserialize_json.ml", line 333, characters 23-38
Called from Ocaml_protoc_plugin__Deserialize_json.deserialize in file "src/ocaml_protoc_plugin/deserialize_json.ml", line 408, characters 15-24
Called from Ocaml_protoc_plugin__Deserialize_json.deserialize in file "src/ocaml_protoc_plugin/deserialize_json.ml", line 417, characters 20-43
Called from Test__Json_enum_initialization.A.from_json_exn in file "test/json_enum_initialization.ml", line 79, characters 4-119

I hit this when working with the GTFS Realtime protocol: TripUpdate.StopTimeUpdate.departure_occupancy_status references the OccupancyStatus enum nested in VehiclePosition.

Thanks for maintaining this library!

@andersfugmann

Copy link
Copy Markdown
Owner

Thanks for the PR. I'll look at this over the weekend. I'd like to look at bit deeper to understand if we can solve the references differently rather than using the lazy keyword. Recursive modules does put some constraints on how other modules can be referenced.

@andersfugmann

Copy link
Copy Markdown
Owner

Looking a bit deeper, I think using lazy is the cleanest solution. Thanks for submitting the PR.

@andersfugmann
andersfugmann merged commit 4f9a68e into andersfugmann:main Sep 26, 2026
3 checks passed
andersfugmann added a commit to andersfugmann/opam-repository that referenced this pull request Sep 27, 2026
CHANGES:

- Add `package_service_name` to generated service modules, providing the
  complete protobuf service path directly (andersfugmann/ocaml-protoc-plugin#49, thanks @Nymphium)
- Use binary mode for the plugin's standard input and output on Windows
  (andersfugmann/ocaml-protoc-plugin#51, thanks @linsyking)
- Fix JSON decoder initialization when a message references an enum
  nested in another message (andersfugmann/ocaml-protoc-plugin#59, thanks @mbickers)
- Read the complete protoc plugin request instead of treating a short
  input read as end-of-file (andersfugmann/ocaml-protoc-plugin#60, thanks @jeong-sik)
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.

2 participants