Commit Graph

8 Commits

Author SHA1 Message Date
YeonGyu-Kim 45452a039c Merge pull request #3731 from yizhifengye/fix/process-cleanup-infinite-loop-epipe
fix(background-agent): detach error listener before running body to s…
2026-05-05 04:24:01 +09:00
auyua9 875fffb7d1 fix(background): exit after fatal cleanup 2026-05-01 16:04:03 +08:00
yizhifengye 49c2a40251 fix(background-agent): detach error listener before running body to stop re-entrant log loop
When shutdown() itself emitted uncaughtException (e.g. EPIPE while closing
a broken pipe), the error listener re-entered itself, re-logged, re-ran
cleanup, and threw EPIPE again. The 6 s forced-exit timer could not fire
because every re-entry stalled the event loop with fresh synchronous work.

Users hit this after v3.17.5 and observed 100+ GB of log lines written to
disk within minutes, with one confirmed report of a 157 GB log file filling
the filesystem.

Detaching the listener with process.off() before running log() + handler()
breaks the loop at the first re-emit: the second event has no listener to
invoke, and the first invocation's scheduleForcedExit() proceeds normally.
2026-04-30 14:47:09 +08:00
YeonGyu-Kim aa79284dc5 fix(background-agent): reset process.exitCode to 0 between cleanup tests
CI test suite exited 1 despite 0 failing tests because process-cleanup.test.ts
assertions left process.exitCode=1 in place. The afterEach hook only reset to
originalExitCode (which starts undefined), not 0, so Bun picked up exitCode=1
on shutdown and reported the shared batch as failing.

Explicitly set process.exitCode = 0 in beforeEach and afterEach so each test
starts and ends with a clean exit state.
2026-04-18 19:57:26 +09:00
YeonGyu-Kim b9d2acdcf9 fix(background-agent): run manager cleanup on uncaughtException and unhandledRejection
Signal handlers covered SIGINT/SIGTERM/SIGBREAK/beforeExit/exit, but a
synchronous throw or a top-level rejected promise terminated the process
without letting TmuxSessionManager (or any other registered manager) run
its shutdown hook. That reliably left orphan tmux panes after an opencode
crash.

Added registration for uncaughtException and unhandledRejection that fan
out through the existing cleanupAll() path, set process.exitCode = 1,
and arm the same 6 second forced-exit guard we use for signals. Test
helpers hold process-level spies so the new tests do not leak listeners
between runs.
2026-04-18 19:32:04 +09:00
YeonGyu-Kim 7d6f47bf3d fix: resolve process-cleanup signal delay and hashline_edit tool name mismatch 2026-03-31 16:59:04 -07:00
YeonGyu-Kim d1e5bd63c1 fix: address Oracle + Cubic review feedback for background-agent refactoring
- Revert getMessageDir to original join(MESSAGE_STORAGE, sessionID) behavior
- Fix dead subagentSessions.delete by capturing previousSessionID before tryFallbackRetry
- Add .unref() to process cleanup setTimeout to prevent 6s hang on Ctrl-C
- Add missing isUnstableAgent to fallback retry input mapping
- Fix process-cleanup tests to use exit listener instead of SIGINT at index 0
- Swap test filenames in compaction-aware-message-resolver to exercise skip logic correctly
2026-02-22 12:14:26 +09:00
YeonGyu-Kim 8d66d5641a test(background-agent): add unit tests for extracted modules
Add 104 new tests across 4 test files:
- error-classifier.test.ts (80 tests): isRecord, isAbortedSessionError, getErrorText, extractErrorName, extractErrorMessage, getSessionErrorMessage
- fallback-retry-handler.test.ts (19 tests): retry logic, fallback chain, concurrency release, session abort, queue management
- process-cleanup.test.ts (7 tests): signal registration, multi-manager shutdown, cleanup on unregister
- compaction-aware-message-resolver.test.ts (13 tests): compaction agent detection, message resolution with temp dirs (pre-existing, verified)

Total background-agent tests: 161 -> 265 (104 new, 0 regressions)
2026-02-22 11:59:06 +09:00