You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Out-of-scope finding from the objectui#4049 development session (PR #4264). Not in that PR's scope — #4049 rules on parseLiteral's tail return s, and this is a different code path (the array branch's catch). Unassigned, filed for triage.
Fact
In packages/app-shell/src/views/metadata-admin/predicate.ts, the in branch matches ^(.+?)\s+in\s+(\[.*\])$ and hands the bracketed text to parseLiteral. That always takes the array branch, which JSON-parses after normalising single quotes:
if (s.startsWith('[') && s.endsWith(']')) {
try {
const json = s.replace(/'([^']*)'/g, (_, inner) => JSON.stringify(inner));
return JSON.parse(json);
} catch {
return []; // <- any unparseable element collapses the whole set
}
}
An element that is not a JSON literal — a path, a bare identifier, a trailing comma — makes JSON.parse throw, the catch returns [], and [].includes(anything) is false. So the predicate is false for every row, with nothing in the console.
Measured (objectui worktree, main @ 11c1e71e8; temporary vitest probe, deleted):
ctx = { data: { type: 'text', a: 'text' } }
data.type in [data.a] -> false // both sides hold 'text'
console.warn calls -> 0
Note the failure is whole-set, not per-element: data.type in ['text', data.a] also collapses to [], so one bad element silently discards the good ones next to it.
Why observation-class (label finding, no pm:queue)
No producer emits this today: every in predicate in the four metadata-admin forms of the installed @objectstack/spec 17.0.0-rc.5 (objectForm / pageForm / viewForm / actionForm) uses literal string arrays. The file header is also explicit that it supports a declared subset (path in ['a','b']), so a path inside the brackets is outside it — a subset boundary, not a broken contract.
It is recorded because it is the same family as objectstack#6936 and objectui#4049 — a silently wrong verdict where the symptom is "the field is not there" — and it is covered by neither. #6936's warning hangs on resolveValue; #4049's new diagnostic sits at parseLiteral's tail, and the array branch provably never reaches that tail (operator coverage measured in PR #4264). Severity judged at filing time is unreliable in both directions, so this is left for the triage seat to grade.
Fail open: an unparseable set is a parse error, and the file's header promises fail-open on parse errors — arguably return [] is the same fail-CLOSED shape objectstack#6936 corrected elsewhere in this file, reached by a third route. This is a semantics change and would need a ruling.
Producer-side: publish-time predicate validation (objectstack#7010 landed the path-resolution half) is where a set element that is not a literal should be refused.
Out-of-scope finding from the objectui#4049 development session (PR #4264). Not in that PR's scope — #4049 rules on
parseLiteral's tailreturn s, and this is a different code path (the array branch'scatch). Unassigned, filed for triage.Fact
In
packages/app-shell/src/views/metadata-admin/predicate.ts, theinbranch matches^(.+?)\s+in\s+(\[.*\])$and hands the bracketed text toparseLiteral. That always takes the array branch, which JSON-parses after normalising single quotes:An element that is not a JSON literal — a path, a bare identifier, a trailing comma — makes
JSON.parsethrow, the catch returns[], and[].includes(anything)is false. So the predicate is false for every row, with nothing in the console.Measured (objectui worktree,
main@11c1e71e8; temporary vitest probe, deleted):Note the failure is whole-set, not per-element:
data.type in ['text', data.a]also collapses to[], so one bad element silently discards the good ones next to it.Why observation-class (label
finding, nopm:queue)No producer emits this today: every
inpredicate in the four metadata-admin forms of the installed@objectstack/spec17.0.0-rc.5 (objectForm/pageForm/viewForm/actionForm) uses literal string arrays. The file header is also explicit that it supports a declared subset (path in ['a','b']), so a path inside the brackets is outside it — a subset boundary, not a broken contract.It is recorded because it is the same family as objectstack#6936 and objectui#4049 — a silently wrong verdict where the symptom is "the field is not there" — and it is covered by neither. #6936's warning hangs on
resolveValue; #4049's new diagnostic sits atparseLiteral's tail, and the array branch provably never reaches that tail (operator coverage measured in PR #4264). Severity judged at filing time is unreliable in both directions, so this is left for the triage seat to grade.Possible directions (not deciding here)
data.a == data.b恒假且无诊断 #4049 ruling: a dev-mode warning when the array branch'scatchfires, naming the predicate and the element that failed. Zero semantic change.return []is the same fail-CLOSED shape objectstack#6936 corrected elsewhere in this file, reached by a third route. This is a semantics change and would need a ruling.data.a == data.b恒假且无诊断 #4049, this whole file is the interim stand-in for@objectstack/formula, and a real CEL evaluator removes the question.Dedup
Searched open objectui issues before filing:
predicate evaluator in-operator array JSON parse failure empty array silent membership metadata-admin— 0 hits;metadata-admin predicate.ts parseLiteral array branch catch returns empty array— 0 hits. Related but distinct: objectui#4049 (the==/!=right-hand side, the tail return), objectstack#6936 (unresolvable path viaresolveValue, fixed), objectstack#5149 (fail-open family). Parallel agents cannot see each other's same-hour filings — race-close this one if a twin exists.Generated by Claude Code