Skip to main content
← Back to list
01Issue
BugShippedSwamp CLIPublicTeam
Assigneeszack

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.

02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 7 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/21/2026, 11:20:35 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
zack assigned zack9/21/2026, 8:56:31 PM
Editable. Press Enter to edit.

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.