Skip to content

fix(generator): escape discriminator JSON names instead of allowlist filtering#340

Merged
erraggy merged 2 commits intomainfrom
fix/discriminator-json-escape
Feb 21, 2026
Merged

fix(generator): escape discriminator JSON names instead of allowlist filtering#340
erraggy merged 2 commits intomainfrom
fix/discriminator-json-escape

Conversation

@erraggy
Copy link
Copy Markdown
Owner

@erraggy erraggy commented Feb 21, 2026

Summary

  • Replaces allowlist-based strings.Map sanitization of discriminator property names with targeted escaping of " and \ only
  • Aligns unmarshal.go.tmpl to use | quote pipe consistently with oneof.go.tmpl

The previous allowlist approach (from #338) would silently break JSON deserialization for any spec with non-alphanumeric discriminator property names — the struct tag wouldn't match the actual JSON key, causing json.Unmarshal to produce empty values.

Context

Found during CodeRabbit review of #338 (posted after merge). The core insight: DiscriminatorJSONName is used in JSON struct tags that must match the real payload key, so we must preserve the original value and only escape Go struct tag syntax breakers.

Test plan

  • go test ./generator/... passes
  • Existing discriminator tests verify correct unmarshal behavior

🤖 Generated with Claude Code

…filtering

The allowlist approach would silently break JSON deserialization for specs
with non-alphanumeric discriminator property names. Escape only the two
characters that break Go struct tag syntax (" and \) so the tag matches
the actual JSON key. Also align unmarshal.go.tmpl to use | quote pipe
consistently with oneof.go.tmpl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 21, 2026

Warning

Rate limit exceeded

@erraggy has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Changes to the code generation logic for handling discriminator JSON names. The discriminator name processing is now escaped (replacing backslashes and quotes) rather than sanitized, and the template is updated to apply this escaped name via a quoted dynamic tag.

Changes

Cohort / File(s) Summary
Discriminator JSON name escaping
generator/template_builders.go, generator/templates/types/unmarshal.go.tmpl
Modified sanitization approach for discriminator JSON names from removing unsafe characters to escaping backslashes and quotes using strings.NewReplacer. Updated unmarshal template to use the dynamically processed DiscriminatorJSONName with quote filtering in the struct tag.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: replacing allowlist filtering with targeted escaping of discriminator JSON names.
Description check ✅ Passed The description is well-related to the changeset, explaining the issue with the previous approach and the rationale for the new escaping strategy.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/discriminator-json-escape

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.72%. Comparing base (d5a1bf1) to head (0f5212d).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #340   +/-   ##
=======================================
  Coverage   84.72%   84.72%           
=======================================
  Files         193      193           
  Lines       27277    27273    -4     
=======================================
- Hits        23110    23107    -3     
+ Misses       2848     2847    -1     
  Partials     1319     1319           
Files with missing lines Coverage Δ
generator/template_builders.go 71.26% <100.00%> (-0.06%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@generator/template_builders.go`:
- Around line 447-450: The discriminator JSON name is only escaping backslashes
and double quotes and thus a backtick in schema.Discriminator.PropertyName will
break the generated Go raw string; in buildOneOfTypeDefinition compute the full
struct tag using the same safe pattern as buildFieldData (e.g., use
fmt.Sprintf("json:%q", <value>)) and assign that to
oneOfData.DiscriminatorJSONName, then remove the `| quote` usage in the template
path so the already-quoted tag is emitted; this keeps escaping consistent and
prevents unescaped backticks from producing invalid Go.
- Around line 447-450: Add a table-driven unit test in the generator package
that round-trips schemas whose discriminator PropertyName includes edge chars
(double-quote, backslash, and both) to ensure the escaping in
template_builders.go works: build Minimal OpenAPI schemas setting
schema.Discriminator.PropertyName to "foo\"bar", "foo\\bar", and "foo\\\"bar",
invoke the same generation path that uses oneOfData.DiscriminatorJSONName,
compile/generate the Go code (or run the generator's transform/templating
functions used in CI), then compile and run a small unmarshal test to assert the
produced struct tags and JSON unmarshal behavior match the original
discriminator names; ensure the test fails if escaping is incorrect and add it
alongside other generator tests as table-driven cases.

In `@generator/templates/types/unmarshal.go.tmpl`:
- Line 4: The struct tag for the discriminator is being double-escaped because
the builder already pre-escapes DiscriminatorJSONName and the template then
applies strconv.Quote via the quote pipe; fix by removing the Quote usage from
the template (unmarshal.go.tmpl) and emit the JSON key as a simple quoted
literal (e.g. `json:"{{.DiscriminatorJSONName}}"`), or alternatively stop
pre-escaping in the template builder so the existing quote pipe can be used;
update either the template (reference .DiscriminatorField and
.DiscriminatorJSONName in unmarshal.go.tmpl) or the builder that sets
DiscriminatorJSONName so only one escaping step occurs.

Comment thread generator/template_builders.go Outdated
Comment thread generator/templates/types/unmarshal.go.tmpl
The builder was escaping " and \ before the template applied
strconv.Quote via | quote, causing double-escaping. Remove
pre-escaping entirely — the | quote pipe in both templates
handles all necessary escaping for Go struct tag string literals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@erraggy
Copy link
Copy Markdown
Owner Author

erraggy commented Feb 21, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@erraggy erraggy merged commit fe1c642 into main Feb 21, 2026
16 checks passed
@erraggy erraggy deleted the fix/discriminator-json-escape branch February 21, 2026 07:06
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