Relationships
#4490 data query rejects CEL list macros: exists(c, ...) fails with Unknown field "c"
Opened by swamp_lord · 11/7/2026
Problem
swamp data query rejects any predicate that uses a CEL list macro, because the variable the macro binds is treated as a record field:
$ swamp data query 'modelName == "golden-gce" && attributes.components.exists(c, c.name == "openssl")'
Error: Server reported data_query_failed: Unknown field "c" in query predicate.
Available: attributes, behaviorName, content, contentType, createdAt, ...This affects exists, all, exists_one, filter and map. So there's no way to query inside a list stored in a record's attributes. For example, CycloneDX SBOMs stored as data can't be searched for a package (attributes.components). A text search with content.contains(...) doesn't match either.
Cause
Checked on main 47eafaa752. Before evaluating, validateFieldReferences (src/domain/data/query_predicate.ts) checks every identifier that collectRootIdentifiers returns. For rcall nodes, collectRootIdentifiers recurses into every argument, so in attributes.components.exists(c, c.name == "openssl"):
- the bound name
c(the first argument); - and its uses (
c.name);
are both collected as root identifiers, and then fail validation.
Grant conditions already handle this. src/domain/access/condition_fields.ts has BINDING_MACROS (all, exists, exists_one, map, filter), and its walker excludes names bound by a comprehension macro ("names bound by a comprehension macro are excluded, so tags.exists(owner, ...)"). The data query validator has no equivalent.
Expected
Inside a macro's body, the name it binds is in scope and isn't validated as a field. The receiver (attributes.components) is still validated as usual. So the query above returns the records whose attributes.components contains an element named openssl. Evaluation already supports macros (cel-js); only the pre-check rejects them.
Suggested fix
- In
collectRootIdentifiers, mirrorcondition_fields.ts: for anrcallwhose method is inBINDING_MACROS, record the bound identifier (the first argument) and exclude it from identifiers collected in the remaining arguments. Keep collecting from the receiver. - Add query predicate tests for
exists,allandfilter, including a nested macro and an unknown field inside a macro body (which should still error). - Mention list macros in
design/enablers/data-query.mdunder Field Validation.
Context
platform-swamp stores each golden GCE image's SBOM as CycloneDX JSON from Syft (about 4,500 components) as swamp data (golden-gce model, lab #4476). We want to ask which images and VMs contain a given package and version without keeping a separate flattened index.
Open
No activity in this phase yet.
Sign in to post a ripple.