Severity: high | Category: correctness | Phase: P0.11
Problem
Verified: POST /tasks/{id}/start?execute=true creates the run (task → IN_PROGRESS), returns 200, then runs execute_agent in a daemon thread whose except only logs + publishes an SSE ErrorEvent + complete_task_sync — it never calls fail_run/stop_run. execute_agent raises ValueError for the very common misconfig (missing ANTHROPIC_API_KEY, unknown provider) before its internal try. The run stays RUNNING; every retry gets 400 "Task already has an active run"; if no SSE client was attached the error is lost entirely.
Evidence
codeframe/ui/routers/tasks_v2.py:704
Acceptance criteria
- The background
except calls runtime.fail_run(...) (resetting task state) before publishing the SSE error.
- Missing API key / unknown provider yields a task that returns to a retryable state, not permanent IN_PROGRESS.
- Test: start-with-execute under a missing key leaves the task non-active afterward.
Dependencies
None
Filed from the SaaS launch-readiness audit. Atomic: one developer, one session. Work order: strictly P0.1 → P3.12 (no forward dependencies).
Severity: high | Category: correctness | Phase: P0.11
Problem
Verified:
POST /tasks/{id}/start?execute=truecreates the run (task → IN_PROGRESS), returns 200, then runsexecute_agentin a daemon thread whoseexceptonly logs + publishes an SSEErrorEvent+complete_task_sync— it never callsfail_run/stop_run.execute_agentraisesValueErrorfor the very common misconfig (missingANTHROPIC_API_KEY, unknown provider) before its internal try. The run stays RUNNING; every retry gets 400 "Task already has an active run"; if no SSE client was attached the error is lost entirely.Evidence
codeframe/ui/routers/tasks_v2.py:704Acceptance criteria
exceptcallsruntime.fail_run(...)(resetting task state) before publishing the SSE error.Dependencies
None
Filed from the SaaS launch-readiness audit. Atomic: one developer, one session. Work order: strictly P0.1 → P3.12 (no forward dependencies).