Filing unassigned — recording, not claiming. Found while implementing #9688 (the cascade escalation depends on this enforcement being live, so its state was re-derived on origin/main).
Measured
content/docs/data-modeling/validation-rules.mdx, in the lookup section right under Multi-value lookups (multiple: true):
<Callouttype="warn">
The `required`-means-non-empty half is **declared but not yet enforced** by the record
validator: today `[]` passes the required check on both insert and update, because the
check treats only `undefined`, `null` and blank strings as missing. Validate emptiness
in application code until that lands (tracked in #9476). The representation guarantee
above (`[]`, never `null`) is live.
</Callout>
Every factual claim in it is now false. Measured on origin/main (packages/objectql/src/validation/record-validator.ts):
Why this is worth a card rather than a shrug
It is not merely stale — it carries an instruction: "Validate emptiness in application code until that lands." An author following it today writes redundant application-side checks against a rule the platform now enforces itself, which is the opposite of the declared-equals-enforced direction the platform is trying to hold. The neighbouring sentence ("the representation guarantee above is live") reads as a deliberate contrast, so the callout does not read as obviously outdated.
Note this is the docs twin of #9781, which corrected the same stale premise where it appeared in code comments (engine.ts and engine-cascade-delete.test.ts). That pass did not reach content/docs.
Shape of the fix
Replace the warn callout with the enforced statement: required on a multi-value lookup means a non-empty array and is enforced by the record validator on insert and update (#9476, per the #9447 ruling); [] is rejected the way null and "" are on a single-value required field. Keep the representation sentence ([], never null) as-is — it is correct and independent.
Refs: #9476 (the enforcement that landed), #9447 (the ruling), #9781 (the same correction on the code-comment side), #9688 (where this was measured).
Filing unassigned — recording, not claiming. Found while implementing #9688 (the cascade escalation depends on this enforcement being live, so its state was re-derived on
origin/main).Measured
content/docs/data-modeling/validation-rules.mdx, in thelookupsection right under Multi-value lookups (multiple: true):Every factual claim in it is now false. Measured on
origin/main(packages/objectql/src/validation/record-validator.ts):isEmptyForRequired— 3 occurrences: the helper plus bothrequiredread sites (the insert/update field check and the second read site further down the file).if (isMissing(value)) return true; return isMultiValueField(def) && Array.isArray(value) && value.length === 0;— so[]on a required multi-value field is rejected on INSERT and UPDATE.[]satisfiesrequiredon amultiple: truelookup — diverges from the #9447 ruling (required means non-empty array) #9476 is closed (merged PR fix(objectql):[]no longer satisfiesrequiredon a multi-value field — the #9447 ruling's enforcement half #9780, squash6a5e6adf1).Why this is worth a card rather than a shrug
It is not merely stale — it carries an instruction: "Validate emptiness in application code until that lands." An author following it today writes redundant application-side checks against a rule the platform now enforces itself, which is the opposite of the declared-equals-enforced direction the platform is trying to hold. The neighbouring sentence ("the representation guarantee above is live") reads as a deliberate contrast, so the callout does not read as obviously outdated.
Note this is the docs twin of #9781, which corrected the same stale premise where it appeared in code comments (
engine.tsandengine-cascade-delete.test.ts). That pass did not reachcontent/docs.Shape of the fix
Replace the warn callout with the enforced statement:
requiredon a multi-value lookup means a non-empty array and is enforced by the record validator on insert and update (#9476, per the #9447 ruling);[]is rejected the waynulland""are on a single-value required field. Keep the representation sentence ([], nevernull) as-is — it is correct and independent.Refs: #9476 (the enforcement that landed), #9447 (the ruling), #9781 (the same correction on the code-comment side), #9688 (where this was measured).