Found while re-pointing PR #4639 (the @objectstack/spec GA pin bump, #4636). Filed
unassigned; not fixed on that branch — it is an authoring-surface decision, not a mirror
of the range lines that card owns.
The gap
@objectstack/spec@17.0.0 adds $like and $ilike to FieldOperatorsSchema. No builder
operator in FilterConditionField emits either, so the server accepts a predicate the filter
UI cannot author.
FAIL packages/fields/src/widgets/__tests__/FilterConditionField.operators.test.ts
> every spec field operator is reachable from the builder (#2942)
> some builder operator emits every spec $-token
AssertionError: FieldOperatorsSchema accepts these but no builder operator can author them:
expected [ '$like', '$ilike' ] to deeply equal []
The gate that catches it is the reachability test added by #2942 — working as designed; this
is its second live catch.
Precedent
This is the same shape as #4023 / #3567 ($icontains unreachable from the filter UI), both
closed. Whatever triage those landed on is the natural starting point, with one difference
worth deciding rather than assuming: $icontains was a case-insensitive variant of an
operator the builder already had, whereas $like / $ilike introduce pattern matching
(wildcards) as a new authoring concept. A builder row for them has to decide whether the
author writes the wildcard characters themselves or the UI composes them, which is a real UX
call and the reason this is not a mechanical addition.
The three options as I read them
- A — add builder operators for both. Closes the gap the gate names. Needs the wildcard
authoring decision above, plus locale strings for the operator labels.
- B — add
$like / $ilike to the test's exemption list with a cited reason. Legitimate
only if the answer is "objectui deliberately does not offer raw pattern matching in the
visual builder" — which is arguable, since a raw LIKE pattern is the one operator where a
mis-authored value silently returns the wrong rows rather than erroring.
- C — leave the gate red. Not an option; it blocks the pin bump.
I have no measured evidence of a consumer asking for pattern matching in the builder today, so
B deserves a fair hearing against A rather than being treated as the lazy answer — but that
call belongs to whoever owns the filter UI's authoring surface, not to the pin-bump card.
Reproduce
Only after the GA pin resolves — on main (still ^17.0.0-rc.6) this test passes.
git checkout claude/issue-4636-spec-pin-ga # PR #4639, at 47c7cc3
pnpm exec vitest run --maxWorkers=2 packages/fields/src/widgets/__tests__/FilterConditionField.operators.test.ts
Blocked-by: #4636 (the failure is only reachable once the GA pin lands).
Generated by Claude Code
Found while re-pointing PR #4639 (the
@objectstack/specGA pin bump, #4636). Filedunassigned; not fixed on that branch — it is an authoring-surface decision, not a mirror
of the range lines that card owns.
The gap
@objectstack/spec@17.0.0adds$likeand$iliketoFieldOperatorsSchema. No builderoperator in
FilterConditionFieldemits either, so the server accepts a predicate the filterUI cannot author.
The gate that catches it is the reachability test added by #2942 — working as designed; this
is its second live catch.
Precedent
This is the same shape as #4023 / #3567 (
$icontainsunreachable from the filter UI), bothclosed. Whatever triage those landed on is the natural starting point, with one difference
worth deciding rather than assuming:
$icontainswas a case-insensitive variant of anoperator the builder already had, whereas
$like/$ilikeintroduce pattern matching(wildcards) as a new authoring concept. A builder row for them has to decide whether the
author writes the wildcard characters themselves or the UI composes them, which is a real UX
call and the reason this is not a mechanical addition.
The three options as I read them
authoring decision above, plus locale strings for the operator labels.
$like/$iliketo the test's exemption list with a cited reason. Legitimateonly if the answer is "objectui deliberately does not offer raw pattern matching in the
visual builder" — which is arguable, since a raw
LIKEpattern is the one operator where amis-authored value silently returns the wrong rows rather than erroring.
I have no measured evidence of a consumer asking for pattern matching in the builder today, so
B deserves a fair hearing against A rather than being treated as the lazy answer — but that
call belongs to whoever owns the filter UI's authoring surface, not to the pin-bump card.
Reproduce
Only after the GA pin resolves — on
main(still^17.0.0-rc.6) this test passes.Blocked-by: #4636 (the failure is only reachable once the GA pin lands).
Generated by Claude Code