From 5e17018edea221c6b8e151b53e77b0a95590a9c2 Mon Sep 17 00:00:00 2001 From: Rolando Santamaria Maso <4096860+jkyberneees@users.noreply.github.com> Date: Sun, 27 Sep 2026 19:00:23 +0200 Subject: [PATCH] fix: record unwind error after cancel relabels run terminal --- cmd/odek/serve_runs.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/odek/serve_runs.go b/cmd/odek/serve_runs.go index 1c5237ca..8efcaf31 100644 --- a/cmd/odek/serve_runs.go +++ b/cmd/odek/serve_runs.go @@ -468,14 +468,19 @@ func (r *serveRun) record(v any) error { r.Status = "running" } case "token", "token_delta": - // A still-draining loop must not mutate a terminal run's result — + // A still-draining loop must not grow a terminal run's result — // the snapshot served by GET /api/runs/{id} would change between // polls after the run already completed/failed. if c, _ := m["content"].(string); c != "" && !runStatusTerminal(r.Status) { r.Result += c } case "error": - if msg, _ := m["message"].(string); msg != "" && !runStatusTerminal(r.Status) { + // First error wins. NOT terminal-gated: the cancel path flips the + // status to "cancelled" first and the unwinding loop's error event + // arrives afterwards — dropping it would leave the run with a + // terminal status but no explanation (and starve clients polling + // for the unwind). Repeated late errors must not overwrite it. + if msg, _ := m["message"].(string); msg != "" && r.Error == "" { r.Error = msg } case "done":