Skip to content

🤖 fix: bound task_terminate with abort support, timeouts, and per-task errors#3720

Merged
ibetitsmike merged 7 commits into
mainfrom
mike/fix-task-terminate-hang
Jul 14, 2026
Merged

🤖 fix: bound task_terminate with abort support, timeouts, and per-task errors#3720
ibetitsmike merged 7 commits into
mainfrom
mike/fix-task-terminate-hang

Conversation

@ibetitsmike

Copy link
Copy Markdown
Contributor

Summary

task_terminate could hang forever with no feedback, no timeout, and no way to cancel: the tool ignored the abort signal, every await down the termination chain was unbounded, and one hung branch rejected the whole call. This PR makes the tool interruptible and bounds every hang path so failures surface as per-task error results instead of silence.

Background

A stuck child stream (e.g. a child wedged in a tool call that does not honor abort) kept streamManager.cancelStreamSafely's await processingPromise pending forever. task_terminate awaited that chain with no deadline, so the tool spun indefinitely; user interrupt showed "INTERRUPTING..." forever because stream teardown waits on the running tool.

Implementation

Layered fix, smallest-risk pieces first:

  • Tool layer (task_terminate.ts): execute now consumes options.abortSignal. Each task ID branch is wrapped in a per-task promise raced via a new raceWithAbortAndTimeout helper (5 min backstop per ID); abort/timeout produce a per-task status: "error" result while other IDs still resolve. A try/catch around each branch keeps one rejection from failing the whole Promise.all.
  • Service layer (taskService.terminateDescendantAgentTask): per descendant, stopStream is bounded at 20s (on timeout the workspace is NOT deleted under a possibly-live stream; siblings continue) and workspaceService.remove at 120s. Errors aggregate instead of aborting the loop. workspaceService.remove's forced path bounds its own stopStream the same way and refuses deletion on timeout.
  • Root fixes: every git command in the worktree deletion path now gets a 60s timeoutMs (execFileAsync already supported it; no timer was installed), and descendant traversal uses a visited set so cyclic task metadata cannot loop forever.

Timeout constants live in src/constants/terminationTimeouts.ts; the race helper in src/node/utils/concurrency/withTimeout.ts registers promise settlement before arming the timer so an already-settled promise wins over a simultaneous timeout.

Explicitly deferred (higher-risk follow-ups): abandoning processingPromise in cleanupAbortedStream (needs a central abandoned-guard for late history/partial writers) and narrowing the task mutex scope.

Validation

  • Unit tests: helper resolve/timeout/abort; abort returns per-task error while sibling IDs resolve; throwing workflow branch yields per-task error; stopStream timeout skips deletion and continues siblings; cyclic traversal terminates.
  • Dogfood UAT in an isolated dev-server sandbox running this branch: spawned a background explore sub-agent and terminated it together with a bogus ID in one call; got terminated + not_found per-task results in seconds, child session/worktree fully removed; re-terminating the same ID returned not_found promptly.

Risks

Termination and workspace removal are shared paths (user-initiated workspace deletion also flows through workspaceService.remove). Behavior change is bounded: previously-infinite waits now end with explicit errors, and a stream-stop timeout now skips deletion where it previously waited forever. If a slow-but-healthy stream stop exceeds 20s, termination reports an error instead of eventually succeeding; the child workspace survives for inspection and can be re-terminated.


Generated with mux • Model: anthropic:claude-fable-5 • Thinking: xhigh • Cost: $20.46

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ca611f9d5c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskService.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c844bc7859

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskService.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01c2291a4a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskService.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88327b7ad7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskService.ts Outdated
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 97e8aca15a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4aa625697e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/tools/task_terminate.ts
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: d7792221f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike ibetitsmike added this pull request to the merge queue Jul 14, 2026
Merged via the queue into main with commit c18a815 Jul 14, 2026
24 checks passed
@ibetitsmike ibetitsmike deleted the mike/fix-task-terminate-hang branch July 14, 2026 00:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant