Relationships
#2311 data.latest().attributes fails with 'No such key' in workflow assert steps
Opened by mellens · 9/21/2026· Shipped 9/21/2026
Summary
data.latest("<name>", "<dataName>").attributes.<field> works in normal CEL
contexts (model method inputs, swamp data query) but fails with "No such
key: attributes" when used in a workflow type: assert step's expr field.
Reproduction
Workflow orca-racers-compare has assert steps that trigger the bug:
- name: assert-no-peeks
task:
type: assert
expr: 'data.latest("race-comparison", "comparison").attributes.racers.all(r, r.peekViolations.size() == 0)'The same CEL expression works when used as an input in a type: model_method
step in the same workflow.
Workaround
Run Jev directly via swamp model method run jev ask --input-file instead of
using the workflow assert step, or avoid .attributes traversal in assert
expressions.
Expected behavior
data.latest().attributes should resolve identically in assert step CEL
expressions and model method input CEL expressions.
Shipped
Click a lifecycle step above to view its details.
zack commented 9/21/2026, 11:21:06 PM
Thanks for this report, @mellens — it landed in PR #2534.
Digging in turned up something worth passing back: the assert-vs-input split is not real. A workflow assert step and a model_method input both construct the same evaluator and fail identically. What actually happened is that data.latest() returns null when no record matches, and a plain dot select off that null makes cel-js raise No such key: attributes with the caret under the field. The caret accused the traversal, so the expression looked broken when the name was the thing that missed.
That is now fixed at the source. The error names the lookup that came back empty:
data.latest("race-comparison", "comparison") found no data record — check the model and data names, or use optional selection if the record may not exist yet.Since the fix sits in the shared evaluator, assert steps, task.inputs, guards and data query all get it. Null returns are unchanged, so guards that use data.latest() as a presence test keep working.
Your workaround should no longer be necessary — and if the comparison record is stored under a composite name from a varying spec, data.latest() takes vary values as a third argument.
Sign in to post a ripple.