Skip to content

Fix: Workaround for process stream hanging after completion (Issue #1280)#1281

Merged
konard merged 5 commits intomainfrom
issue-1280-b52df2042884
Feb 13, 2026
Merged

Fix: Workaround for process stream hanging after completion (Issue #1280)#1281
konard merged 5 commits intomainfrom
issue-1280-b52df2042884

Conversation

@konard
Copy link
Contributor

@konard konard commented Feb 13, 2026

Summary

This PR addresses issue #1280 where the solve command using --tool claude gets stuck after successful completion, requiring manual CTRL+C to terminate.

Root Cause

The hang is caused by command-stream v0.9.4's stream() async iterator behavior:

  1. stream() waits for both process exit AND stdout/stderr pipe close before ending
  2. If the CLI process keeps stdout open after sending the result event, pumpReadable() hangs indefinitely
  3. finish() never fires → 'end' event never emitted → for await loop never terminates
  4. Additionally, stream() does NOT yield {type:'exit'} chunks, making exit code detection via chunk.type === 'exit' dead code in 6 source files

This is NOT a Claude CLI bug — the lines "Cost captured" and "Captured result summary" are printed by our code inside the for await loop after the result event arrives. The hang occurs when command-stream's stream() iterator doesn't terminate because the underlying process keeps stdout open.

Evidence from logs — 5 min 26 sec gap after result event:

Timestamp Event
21:10:17.168Z Result event received (success)
21:10:17.169Z Cost captured, result summary processed
5 min 26 sec for await loop stuck in command-stream stream()
21:15:43.123Z User interrupted with CTRL+C (exit code 130)

Solution

Implemented a configurable timeout workaround in src/claude.lib.mjs:

  1. Track when the result event is received
  2. Start a timeout (default 30s, configurable via HIVE_MIND_RESULT_STREAM_CLOSE_MS)
  3. If the stream doesn't close within that time:
    • Send SIGTERM to the process
    • Wait 2 seconds
    • Send SIGKILL if still running
  4. Added detailed verbose logging with timestamps for debugging

Additional Changes

  • Added timeouts.resultStreamCloseMs to src/config.lib.mjs (configurable via env var)
  • Added comments documenting command-stream chunk.type === 'exit' dead code
  • Updated case study in docs/case-studies/issue-1280/ANALYSIS.md with corrected root cause
  • Updated changeset with accurate description

Upstream Bug Reports

Files Changed

  • src/claude.lib.mjs — Timeout workaround + dead code documentation
  • src/config.lib.mjs — Added resultStreamCloseMs timeout config
  • .changeset/issue-1280-claude-cli-hang-workaround.md — Updated changeset
  • docs/case-studies/issue-1280/ANALYSIS.md — Corrected root cause analysis

Testing

  • All unit tests pass
  • Linting passes (eslint)
  • Formatting passes (prettier)
  • Syntax validation passes
  • File line count under 1500 limit (1466 lines)

Issue Reference

Fixes #1280


This PR was created by the AI issue solver

Adding CLAUDE.md with task information for AI processing.
This file will be removed when the task is complete.

Issue: #1280
@konard konard self-assigned this Feb 13, 2026
@konard konard changed the title [WIP] --tool claude command execution is stuck just after the success, and I had to manually interrupt it Fix: Workaround for Claude CLI hanging after completion (Issue #1280) Feb 13, 2026
@konard konard force-pushed the issue-1280-b52df2042884 branch from a125364 to 1c75bcf Compare February 13, 2026 21:32
Claude Code CLI sometimes hangs indefinitely after sending the final
result event without closing stdout. This fix adds a 30-second timeout
after receiving the result event. If the stream doesn't close within
that time, the process is forcefully terminated with SIGTERM/SIGKILL.

Root Cause Analysis:
- Claude CLI sends {"type":"result","subtype":"success"} event
- But process keeps stdout open and doesn't exit
- for-await loop in streaming code waits forever
- User has to manually CTRL+C to terminate

Solution:
- Track when result event is received
- Set 30s timeout to force-kill process if stream doesn't close
- Use SIGTERM first, then SIGKILL if needed
- Log verbose messages for debugging

Case Study:
- Full timeline reconstruction in docs/case-studies/issue-1280/
- Original log shows 5+ minute hang after successful completion
- Screenshots preserved for reference
- Full log available at gist (too large for git)

Reported upstream:
- anthropics/claude-code#25629

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard konard force-pushed the issue-1280-b52df2042884 branch from 1c75bcf to ed87517 Compare February 13, 2026 21:38
@konard konard marked this pull request as ready for review February 13, 2026 21:45
@konard
Copy link
Contributor Author

konard commented Feb 13, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $15.594683
  • Calculated by Anthropic: $10.381832 USD
  • Difference: $-5.212851 (-33.43%)
    📎 Log file uploaded as Gist (4043KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Contributor Author

konard commented Feb 13, 2026

I don't believe it is the problem with claude command, instead I think

}
💰 Anthropic official cost captured from success result: $1.917418
📝 Captured result summary from Claude output

That indicates, that is our solve command code is hanging. Because these lines are added after claude command is executed, and if not, just make sure we don't mix the output, and do our output only after claude command is finished, so there will be clear distinction and border of responsibilities.

Please double check our recent releases. Captured result summary from Claude output was added not long ago. If we need to add more debug data in --verbose mode just do it.

Anyway we should apply workaround to successfully terminate claude command if we got final result summary, but not the result code of the command. If we are using command-stream or other function to execute claude command, double check that this library does not have the problem. Anyway if possible try to reproduce it. And add all necessary debug output as we do it in --verbose mode, and also do all nessesary workaround. And double check our latest code changes, may be we broke something there.

Ensure all changes are correct, consistent, validated, tested and fully meet all discussed requirements (check issue description and all comments in issue and in pull request). Ensure all CI/CD checks pass.

@konard konard marked this pull request as draft February 13, 2026 21:51
@konard
Copy link
Contributor Author

konard commented Feb 13, 2026

🤖 AI Work Session Started

Starting automated work session at 2026-02-13T21:51:04.900Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback.

konard and others added 2 commits February 13, 2026 22:57
…Issue #1280)

Root cause: command-stream v0.9.4's stream() async iterator waits for both
process exit AND stdout/stderr pipe close before ending. If the CLI process
keeps stdout open after sending the result event, pumpReadable() hangs,
finish() never fires, and the stream iterator never terminates. This is NOT
a Claude CLI bug — it's a command-stream library limitation.

Additionally, command-stream stream() does NOT yield {type:'exit'} chunks,
making the exit code detection via chunk.type==='exit' dead code (added
comment noting this for all 6 affected source files).

Changes:
- Add configurable timeout: HIVE_MIND_RESULT_STREAM_CLOSE_MS (default 30s)
- Improve verbose debug logging with timestamps and process state info
- Add detailed root cause comments explaining command-stream behavior
- Update case study with corrected analysis (command-stream, not Claude CLI)
- Update changeset with accurate description
- Filed upstream issue: link-foundation/command-stream#155

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard konard changed the title Fix: Workaround for Claude CLI hanging after completion (Issue #1280) Fix: Workaround for process stream hanging after completion (Issue #1280) Feb 13, 2026
@konard konard marked this pull request as ready for review February 13, 2026 22:10
@konard
Copy link
Contributor Author

konard commented Feb 13, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $9.101580
  • Calculated by Anthropic: $6.904549 USD
  • Difference: $-2.197031 (-24.14%)
    📎 Log file uploaded as Gist (1670KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard konard merged commit 135c729 into main Feb 13, 2026
21 checks passed
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.

--tool claude command execution is stuck just after the success, and I had to manually interrupt it

1 participant