Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

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, mirror condition_fields.ts: for an rcall whose method is in BINDING_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, all and filter, including a nested macro and an unknown field inside a macro body (which should still error).
  • Mention list macros in design/enablers/data-query.md under 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.

02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

11/7/2026, 12:09:12 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.