Skip to content

[bug] Clarify and Enforce Terminal Task State Precedence During Races Between Canceled, Completed, and Failed Outcomes #401

Description

@darrelmiller

Background

PR #364 introduces logic to forcibly move a task into the Failed state if an exception occurs in background processing, even if other terminal transitions may be racing with it (e.g., the task might be Completed or Canceled nearly simultaneously).

This approach improves situations where tasks are stuck in Working due to handler crashes, but it raises questions about which terminal outcome "wins" if multiple terminal updates race.

Discussion Points / Concerns

  • Race condition: There is a window where a background failure process may overwrite an already persisted terminal state (such as Completed or Canceled) with Failed. This is because the recovery code pre-reads the state outside the lock and there is no atomic check-and-set for terminal transitions.
  • Intended final state precedence:
    • Should an execution failure in a background drain always win and mark the task Failed, even if the user or normal agent flow already produced Completed or Canceled?
    • Or should Completed/Canceled be preserved as the final state if they're saved first, treating background failures as only relevant if the task is still non-terminal?
  • Example scenario:
    • A user cancels a seemingly hung task, triggering a Canceled transition, but background work later fails—should Failed overwrite Canceled, or should Canceled be considered the correct terminal state?
  • Current behavior: The current logic means last terminal state wins. This could surprise users (e.g., UI shows Failed even though user intentionally canceled), and may not match the intended experience.
  • Recommendation:
    • Decide on and document the desired precedence of terminal state transitions (Failed, Completed, Canceled, etc.).
    • Consider enforcing this precedence atomically (lock + re-check, or in task projection) to avoid accidental overwrites.
    • Update tests and documentation to clarify which transitions are allowed and which are not.
    • Consider passing appropriate cancellation tokens in all recovery paths as a related minor improvement.

Next Steps

  • Team should agree on "terminal state precedence" policies to guide resolution and implementation.
  • If user intent (explicit cancel) should always result in Canceled, implementation must guard against overwriting with Failed due to late background errors.
  • If execution correctness should always win, document and surface this for users.

This issue is to track the above questions and drive consensus and a follow-up fix/clarification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions