Repository navigation
Conversation
🦋 Changeset detectedLatest commit: 72d56c7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
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 |
|
You're right that walking Worth flagging one consequence of skipping the subtree rather than trying to classify: a nested object inside
|
418fbb3 to
10e2ea0
Compare
04deb9f to
62fe88d
Compare
| if (parent.not === chain[i]) return true; | ||
| } | ||
| return false; | ||
| }; |
There was a problem hiding this comment.
isUnderNot misses $ref sibling not
Medium Severity
isUnderNot walks the resolved parents stack, so a not written next to $ref is invisible: Schema enter receives the resolved target, which does not own that not. The same gap hits the ref visitor after Schema leave. Valid OAS 3.1 $ref + sibling not forms still report required names inside not.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 62fe88d. Configure here.
|
Bugbot has a real one here, and it predates this PR. A Restricted:
$ref: '#/components/schemas/Contact'
not:
required:
- missinggives The cause is what Bugbot describes: the ref node owns the I ran those shapes against d1a2e42 as well and they report identically there, so this is not a regression from this PR. The case this PR does change is a plain Closing the gap means deciding containment from the reported location's pointer rather than from the resolved parents stack, and that has to exclude a property literally named |
62fe88d to
a4f0fd9
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a4f0fd9. Configure here.
| if (parent.not === chain[i]) return true; | ||
| } | ||
| return false; | ||
| }; |
There was a problem hiding this comment.
Nested not refs skip named schemas
Medium Severity
isUnderNot treats every descendant of a lexical not as skipped. A named schema first reached through a nested $ref (for example not.allOf) is skipped and marked seen, so its own required is never checked. The identity guard only covers a $ref that is the direct value of not.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit a4f0fd9. Configure here.
Co-authored-by: Cursor <cursoragent@cursor.com>
The not check ran only in the Schema visitor, so a required sibling of a $ref under not was still validated by the ref visitor. Both visitors now share one isUnderNot helper, which also covers a $ref nested deeper in a composition under not.
isUnderNot also matched the resolved target of not: { $ref }, so a named
schema reached first through such a ref had its own required list skipped and,
when nothing else referenced it, never validated at all. Whether the finding
appeared then depended on walk order. Match only an ancestor's own not value;
the four cases the skip exists for are all lexical.
a4f0fd9 to
72d56c7
Compare


What/Why/How?
findCompositionRootnow walksnotthe same way it already walksallOf/anyOf/oneOf, sono-required-schema-properties-undefinedchecksrequirednames insidenotagainst the enclosing object (the usual JSON Schema form for mutual exclusion / absence).findCompositionRootdid not treatnotas the same-instance relationship, so the (usually empty)notsubschema was checked alone.Typos inside
notthat do not exist on the enclosing schema still report.Decision: walk
notlike the other composition keywords (option (b) on #3104).Alternative: skip every
requiredundernot(option (a)).Why: walking
notmatches the existingisCompositionChildhelper and still catches undeclared names; can switch to (a), or also walkif/then/else.Reference
Fixes #3104
Testing
Contact.not.required).notis silent; an extra undeclared name insidenotstill reports.Screenshots (optional)
Check yourself
Security
Note
Low Risk
Targeted lint-rule behavior change with broad test coverage; no runtime API or security impact.
Overview
Fixes false positives in
no-required-schema-properties-undefinedwhen schemas usenot: { required: [...] }for mutual exclusion (e.g. “must not require both email and phone”).The rule now skips
requiredarrays that sit lexically under anotkeyword, because those names describe absence constraints, not missingpropertiesdeclarations. The same skip applies on composed$refpaths when the ref (or its siblings) is directly undernot; named schemas still get their ownrequiredchecked when visited elsewhere, including when referenced only from anotexclusion.Docs and unit tests cover
not.requiredwith declared/undeclared names,$refsiblings, nested composition, and the case where a badrequiredon a referenced schema is still reported.Reviewed by Cursor Bugbot for commit 72d56c7. Bugbot is set up for automated code reviews on this repo. Configure here.