Skip to content

fix: wrap waitForCompactionRetry with abort signal to prevent session lock leak#12227

Closed
Yida-Dev wants to merge 1 commit intoopenclaw:mainfrom
Yida-Dev:fix/compaction-retry-abort-signal
Closed

fix: wrap waitForCompactionRetry with abort signal to prevent session lock leak#12227
Yida-Dev wants to merge 1 commit intoopenclaw:mainfrom
Yida-Dev:fix/compaction-retry-abort-signal

Conversation

@Yida-Dev
Copy link
Copy Markdown
Contributor

@Yida-Dev Yida-Dev commented Feb 9, 2026

Summary

  • After an embedded run is aborted (timeout or external abort), waitForCompactionRetry() hangs indefinitely because it waits for compaction events that never arrive post-abort
  • This prevents the finally block from executing, so clearActiveEmbeddedRun() and sessionLock.release() are never called
  • The session stays in ACTIVE_EMBEDDED_RUNS and the .lock file remains — the agent becomes permanently unresponsive until gateway restart
  • Fix: wrap waitForCompactionRetry() with the existing abortable() helper, matching the pattern already used for activeSession.prompt() on lines 820-822

Test plan

  • Existing compaction retry tests pass (5 tests)
  • The fix follows the exact same abortable() pattern used 2 lines above for activeSession.prompt()

Closes #12085

Co-Authored-By: Claude Opus 4.6 [email protected]

Greptile Overview

Greptile Summary

This change wraps the waitForCompactionRetry() await in the existing abortable() helper inside runEmbeddedAttempt(). That ensures an external abort/timeout can break out of the post-prompt compaction wait and allow the surrounding finally blocks to run, preventing embedded session state (including the session write lock) from being left behind in a stuck state after an aborted run.

The implementation matches the established pattern already used for activeSession.prompt() in the same function, so behavior stays consistent across the two long-running awaits in the embedded run lifecycle.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk.
  • The diff is a single-line change using an already-present abortable() helper, localized to the embedded run attempt flow. It aligns with the existing abort handling pattern used for activeSession.prompt() and directly addresses a hang that could prevent the cleanup finally blocks from releasing session state and locks.
  • src/agents/pi-embedded-runner/run/attempt.ts

After an embedded run is aborted, waitForCompactionRetry() can hang
indefinitely because it waits for compaction events that may never
arrive post-abort. This prevents the finally block from executing,
so clearActiveEmbeddedRun() and sessionLock.release() are never
called — leaving the session permanently locked and unresponsive.

Wrap the call with the existing abortable() helper (same pattern used
for activeSession.prompt() on line 820-822) so the abort signal
properly interrupts the compaction wait.

Closes openclaw#12085

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@sebslight
Copy link
Copy Markdown
Member

Closing as duplicate of #15449. If this is incorrect, please contact us.

@sebslight sebslight closed this Feb 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Embedded run never exits after abort: waitForCompactionRetry() not tied to abort signal, session stays active and locked

2 participants