Skip to content

fix(schema): prevent crash validating unions of object arrays#1638

Open
xianjianlf2 wants to merge 1 commit into
arktypeio:mainfrom
xianjianlf2:fix/array-union-in-operator-crash-1458
Open

fix(schema): prevent crash validating unions of object arrays#1638
xianjianlf2 wants to merge 1 commit into
arktypeio:mainfrom
xianjianlf2:fix/array-union-in-operator-crash-1458

Conversation

@xianjianlf2

Copy link
Copy Markdown

Problem

When a union of array types with object element bases (e.g. { objB: string }[] | { objC: string }[]) was validated against an array containing a non-object element, a TypeError: Cannot use 'in' operator was thrown.

Inside a union branch, traversal runs in fail-fast mode and ctx.currentErrorCount saturates at 1, so an intersection's basis (object/proto) failure guard (currentErrorCount > errorCount) could not detect a newly added error once an earlier element in the same branch had already errored. The sequence node then continued iterating and applied the element's structure check (key in data) to a primitive, throwing.

Fix

SequenceNode now mirrors StructureNode by bailing out of remaining elements in fail-fast mode, both in traverseApply and in its compiled output, so a failed element basis short-circuits before the unguarded in check runs. Top-level (non-fail-fast) validation is unchanged and still collects every element error.

Testing

Added a regression test in ark/type/__tests__/union.test.ts covering a union of object arrays validated against an array containing a non-object element, confirming it no longer throws and reports a proper validation error.

Closes #1458

When a union of array types with object element bases (e.g.
`{ objB: string }[] | { objC: string }[]`) was validated against an
array containing a non-object element, a `TypeError: Cannot use 'in'
operator` was thrown.

Inside a union branch, traversal runs in fail-fast mode and
`ctx.currentErrorCount` saturates at 1, so an intersection's basis
(object/proto) failure guard (`currentErrorCount > errorCount`) could
not detect a newly added error once an earlier element in the same
branch had already errored. The sequence node then continued iterating
and applied the element's structure check (`key in data`) to a
primitive, throwing.

SequenceNode now mirrors StructureNode by bailing out of remaining
elements in fail-fast mode, both in `traverseApply` and in its compiled
output, so a failed element basis short-circuits before the unguarded
`in` check runs. Top-level (non-fail-fast) validation is unchanged and
still collects every element error.

Closes arktypeio#1458

@pullfrog pullfrog Bot left a comment

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.

✅ No new issues found.

Reviewed changes — this PR prevents a hard TypeError crash when validating a union of object arrays against an array containing a primitive element, by making SequenceNode bail out of further element traversal in fail-fast mode (e.g. inside a union branch), matching the behavior already implemented in StructureNode.

  • SequenceNode.traverseApply now checks ctx.failFast && ctx.currentErrorCount > errorCount after each element and returns early, stopping traversal of later elements once one element has failed inside a fail-fast context.
  • SequenceNode.compile now initializes an errorCount snapshot and emits js.returnIfFailFast() after each prefix, defaultable/optional, variadic, and postfix element in the generated Apply traversal, producing the compiled equivalent of the runtime short-circuit.
  • Regression test added to ark/type/__tests__/union.test.ts covering both element-orderings from issue #1458.

Pullfrog  | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To do

Development

Successfully merging this pull request may close these issues.

Array union TypeError

1 participant