Founder hit this reviewing a FAILED run in the app: the execution row carries cost/model/duration but context, error, result, and trigger_name are all null. The run page can only say "FAILED — dispatched" because the ledger holds nothing else.
The runner already knows all of it at exit: the task text it was launched with, the terminal reason (api_error / completed / killed), the last error line from the provider stream, and the final message. None of it is persisted to the execution row.
Required at run finalization (success AND failure):
context.task = the dispatch task text (capped to a sane length).
error = terminal reason + last provider/API error when status != success (e.g. "api_error: response stalled mid-stream after 25 turns").
result.summary = the agent's final message (or first N chars) when one exists.
- Backstop: the cleanup path must also write these — lane deaths are exactly when they matter most.
Related but distinct: #1129 (session-to-ledger linkage), #1130 (deliver-and-stop classing), #1100 (background lanes emit no events — the app's /runs/{id}/events 404s for them), api#203 (zombie liveness). This one is purely: write the postmortem fields the runner already holds.
Founder hit this reviewing a FAILED run in the app: the execution row carries cost/model/duration but
context,error,result, andtrigger_nameare all null. The run page can only say "FAILED — dispatched" because the ledger holds nothing else.The runner already knows all of it at exit: the task text it was launched with, the terminal reason (api_error / completed / killed), the last error line from the provider stream, and the final message. None of it is persisted to the execution row.
Required at run finalization (success AND failure):
context.task= the dispatch task text (capped to a sane length).error= terminal reason + last provider/API error when status != success (e.g. "api_error: response stalled mid-stream after 25 turns").result.summary= the agent's final message (or first N chars) when one exists.Related but distinct: #1129 (session-to-ledger linkage), #1130 (deliver-and-stop classing), #1100 (background lanes emit no events — the app's /runs/{id}/events 404s for them), api#203 (zombie liveness). This one is purely: write the postmortem fields the runner already holds.