Skip to content

fix(core): fix Ajv error discriminator #2720

Open
harshit078 wants to merge 13 commits intoRedocly:mainfrom
harshit078:fix-ajv-validation-discrimator
Open

fix(core): fix Ajv error discriminator #2720
harshit078 wants to merge 13 commits intoRedocly:mainfrom
harshit078:fix-ajv-validation-discrimator

Conversation

@harshit078
Copy link
Copy Markdown
Contributor

@harshit078 harshit078 commented Apr 6, 2026

What/Why/How?

Reference

Testing

Screenshots (optional)

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

Note

Medium Risk
Touches response schema validation by preprocessing schemas before Ajv, which could change validation outcomes for discriminator-based schemas if the discriminator keyword was previously relied on during validation. Risk is mitigated by added tests covering the reported allOf+not discriminator pattern and existing validation paths.

Overview
Fixes a crash in checkSchema when Ajv is configured with discriminator: true but the OpenAPI discriminator property uses valid constraint compositions like allOf + not.

This preprocesses the dereferenced response schema by removing discriminator keywords (via new removeDiscriminatorsFromSchema) before running Ajv, and adds regression tests for the discriminator/constraint pattern plus the new utility.

Reviewed by Cursor Bugbot for commit d7ca08e. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: d7ca08e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@redocly/respect-core Patch
@redocly/cli Patch
@redocly/openapi-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@harshit078 harshit078 marked this pull request as ready for review April 8, 2026 12:17
@harshit078 harshit078 requested review from a team as code owners April 8, 2026 12:17
@harshit078 harshit078 changed the title fix: Respect doesn't resolve complex constraint pattern fix(core): Respect doesn't resolve complex constraint pattern Apr 9, 2026
@harshit078 harshit078 changed the title fix(core): Respect doesn't resolve complex constraint pattern fix(core): fix Ajv error discriminator Apr 9, 2026
@DmitryAnansky
Copy link
Copy Markdown
Contributor

@harshit078
Could you please elaborate on why you believe removing discriminators is a good fix for this issue?
Have you considered any alternative approaches?

@@ -0,0 +1,5 @@
---
"@redocly/respect-core": major
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please use patch for fixes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure

@harshit078
Copy link
Copy Markdown
Contributor Author

@DmitryAnansky sure,
my intent/logic behind creating a function which removes discriminators is because when I researched about OpenAPI discriminator schema I found out that it serves mainly one purpose which is its optimises routing and act as routing shortcut.
The alternatives I considered before submitting PR were -

  • Selective stripping: this was more complex than intented and had to have many edge cases
  • making discriminator as false : it would have affected globally rather than per schema
  • brute force with simple Catch error and retry: same as first point

This is my POV of issue. If you think approach can be better, I am ready to implement it. Thanks :)


if ('discriminator' in node) {
delete node.discriminator;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Strips any key named "discriminator" not just OpenAPI keyword

Medium Severity

stripDiscriminators removes every key named discriminator from every nested object, not just the OpenAPI discriminator keyword from Schema Objects. When a schema has a data property literally named discriminator inside properties (or $defs, definitions, patternProperties, etc.), the function deletes that property definition, silently corrupting the schema used for validation. The check needs to distinguish the OpenAPI discriminator keyword (which is a sibling of oneOf/anyOf and contains propertyName) from regular map entries.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c690a69. Configure here.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d7ca08e. Configure here.


stripDiscriminators(schema);
return schema;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Function mutates input, failing its own non-mutation test

High Severity

removeDiscriminatorsFromSchema mutates its input in-place via delete node.discriminator in stripDiscriminators, but the test "should not mutate the original schema" asserts that the original object retains its discriminator property after the call. This test will fail. The function needs to deep-clone the schema before stripping, or the test expectation is wrong. In the current call site the mutation is masked because removeWriteOnlyProperties already deep-clones, but the function's contract is broken.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d7ca08e. Configure here.

strictSchema: false,
inlineRefs: false,
validateSchema: false,
discriminator: true,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @harshit078 for the contribution. You don't need to remove discriminator manually, you can just drop this setting from the Ajv and it will not cause the error. The issue looks more deeply. Could you please investigate the root cause?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure, I'll look into it

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.

3 participants