Skip to content

Background task_status reports cancelled after compaction while child session keeps running #28995

Closed as not planned

Description

@alvinunreal

Summary

When a background subagent session triggers compaction/context overflow handling, the background job can be marked cancelled even though the child session continues running and eventually finishes. After this happens, task_status reports state: cancelled while session status events still show the child session as busy.

This looks like a mismatch between BackgroundJob fiber state and the actual child session lifecycle.

Repro

  1. Start OpenCode with native background subagents enabled.
  2. Launch a background task that reads enough large files to trigger compaction/context overflow.
  3. Reuse/resume the same background task/session and continue reading large files.
  4. Wait for compaction to occur.
  5. Call task_status for the task id.

Observed task id in my repro: ses_1aa9421abffeuASVxya3Kva4Th.

Expected

If the child session is still busy/running after compaction, task_status should report running or otherwise reflect the live child session state. Compaction should not make the background task look cancelled unless the child session was actually stopped.

Actual

task_status returned:

task_id: ses_1aa9421abffeuASVxya3Kva4Th
state: cancelled

<task_error>

</task_error>

But the child session continued running after that and eventually reached idle/finished.

Sanitized log timeline

OpenCode log:

15:21:30 context_length_exceeded for child session ses_1aa9421abffeuASVxya3Kva4Th
15:21:30 compaction agent started for same session
15:21:32 bus type=session.compacted publishing
15:22:01 task_status result observed as state=cancelled
15:22:07+ repeated session busy events for the same child session after cancelled state
15:22:59 child session eventually emitted idle/finished behavior

Plugin-side lifecycle logs from a local OpenCode plugin also showed the mismatch:

15:22:01 parsed task status output { taskID: ses_1aa9421abffeuASVxya3Kva4Th, state: cancelled }
15:22:01 background job status updated { state: cancelled }
15:22:07 session busy event received { sessionId: ses_1aa9421abffeuASVxya3Kva4Th, backgroundJobState: cancelled }
15:22:08 session busy event received { sessionId: ses_1aa9421abffeuASVxya3Kva4Th, backgroundJobState: cancelled }
...
15:22:59 session status idle received for same child session

Source pointers

From current source, this appears related to:

  • packages/opencode/src/background/job.ts
    • BackgroundJob.start marks interrupted job fibers as cancelled via Cause.hasInterruptsOnly(cause) ? "cancelled" : "error".
  • packages/opencode/src/tool/task.ts
    • background task wraps child session execution in BackgroundJob.start({ id: nextSession.id, run: runTask() ... }).
  • packages/opencode/src/tool/task_status.ts
    • task_status trusts BackgroundJob.status before checking live session status / latest assistant state.
  • packages/opencode/src/session/compaction.ts and packages/opencode/src/session/prompt.ts
    • compaction can create synthetic continuation messages and continue the same session after context overflow.

Possible fix direction

Either:

  1. task_status should not trust BackgroundJob.status === cancelled if the child session status is currently busy/retry; or
  2. BackgroundJob should not mark a background task cancelled until the child session is actually stopped/deleted, not merely because the wrapper fiber was interrupted during compaction/continuation.

This matters for background orchestration because callers will treat cancelled as terminal and may stop tracking or reuse the session incorrectly while it is still doing work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions