Skip to content

fix: contains on an unset field no longer throws - #436

Merged
jsm1t merged 1 commit into
mainfrom
fix/contains-unset-field
Sep 16, 2026
Merged

jsm1t merged 1 commit into
mainfrom
fix/contains-unset-field

Conversation

@jsm1t

@jsm1t jsm1t commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

contains any / contains all rejected any non-array value, conflating "the field is not set" with "the field is not a set". The predicate runs per resource, so one resource without the field failed the whole query:

custom(fields(orderNumbers contains any ("R-123")))
→ The field 'orderNumbers' does not support this expression.

Real commercetools treats an unset set as having no members and just doesn't match it.

Fix: an unset (undefined/null) field evaluates to false. A field that is present but is not a set still raises a PredicateError — that's a genuine type mismatch.

Tests cover both, standalone and combined with or / nested(...). Verified the first fails without the fix. Full suite: 930 passing.

🤖 Generated with Claude Code

The `contains any` / `contains all` handler rejected any non-array value,
conflating "the field is not set" with "the field is not a set". Since the
predicate runs per resource, a single resource without the field failed the
entire query:

    custom(fields(orderNumbers contains any ("R-123")))
    → The field 'orderNumbers' does not support this expression.

Real commercetools treats an unset set as having no members and simply does
not match it. An unset (undefined or null) field now evaluates to false; a
field that is present but is not a set still raises a PredicateError, since
that is a genuine type mismatch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 52ccd3e

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

This PR includes changesets to release 1 package
Name Type
@labdigital/commercetools-mock 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

@jsm1t
jsm1t merged commit 8a8a282 into main Sep 16, 2026
10 checks passed
@jsm1t
jsm1t deleted the fix/contains-unset-field branch September 16, 2026 14:48
jsm1t pushed a commit that referenced this pull request Sep 16, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.

⚠️⚠️⚠️⚠️⚠️⚠️

`main` is currently in **pre mode** so this branch has prereleases
rather than normal releases. If you want to exit prereleases, run
`changeset pre exit` on `main`.

⚠️⚠️⚠️⚠️⚠️⚠️

# Releases
## @labdigital/commercetools-mock@5.0.0-beta.2

### Patch Changes

- [#436](#436)
[`8a8a282`](8a8a282)
Thanks [@jsm1t](https://github.com/jsm1t)! - Fix `contains any` /
`contains all` throwing on resources where the field is not
  set.
  
  The handler rejected any non-array value, so a predicate such as
  `custom(fields(orderNumbers contains any ("R-123")))` raised
`The field 'orderNumbers' does not support this expression.` as soon as
one
resource in the collection lacked the field — failing the entire query
rather
than filtering that resource out. Real commercetools treats an unset set
as
  having no members, so it simply does not match.
  
An unset (`undefined` or `null`) field now evaluates to `false`. A field
that is
present but is not a set still raises a `PredicateError`, since that is
a
  genuine type mismatch.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

2 participants