anthropics / anthropics/claude-agent-sdk-python

CLI version check timeout can hang indefinitely while waiting for termination

Open
#1,162 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
8.1k
Forks
1.3k
PR merge metrics
PR metrics pending

Description

### Summary

`SubprocessCLITransport._check_claude_version()` has a two-second timeout, but its cleanup performs an unbounded process wait outside that timeout.

### Affected code

`src/claude_agent_sdk/_internal/transport/subprocess_cli.py:1024-1065`

### Current behavior

The `anyio.fail_after(2)` scope covers process creation and reading the version output. In `finally`, the code calls:

```python
version_process.terminate()
await version_process.wait()
```

The wait is outside the timeout and there is no kill fallback. If the executable ignores or fails to respond to SIGTERM, `wait()` never returns.

Exceptions are also suppressed, so this path does not expose useful diagnostic information.

### Why this matters

The version check runs during transport connection. A stale, wrapped, broken, or malicious executable at the configured CLI path can therefore hang every SDK connection indefinitely despite the documented two-second timeout.

### Expected behavior

The entire probe, including process cleanup and reaping, should have a finite upper bound.

### Possible fix

Use bounded subprocess shutdown:

1. Terminate the process.
2. Wait for a short bounded interval.
3. Kill it if still running.
4. Await/reap it under another bounded interval.
5. Preserve cancellation semantics while suppressing only expected cleanup errors.

A regression test can use a mocked process whose first `wait()` does not complete and assert that `kill()` is called and connection continues within the deadline.

This follow-up was mentioned as out of scope in PR #1082, but I found no dedicated issue or active implementation.

### Environment

- Repository revision: current `main` audit at SDK version 0.2.128
- Bundled CLI version: 2.1.220
- Python test suite: 1,291 passed, 5 skipped
- Ruff and mypy: clean

I searched the existing issues and pull requests using the affected symbols and behavior before filing this.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.