anthropics / anthropics/claude-agent-sdk-python

Exception in the prompt AsyncIterable is swallowed at debug level and query() hangs forever

Aberta
#1,108 0 comentários 0 reações 0 responsáveis Ver no GitHub
bug
Linguagem predominante
Python
Estrelas
8.1k
Forks
1.3k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

## Symptom

If the `AsyncIterable` passed as `prompt=` to `query()` raises — a bug in the caller's generator, or a message that fails `json.dumps` — the exception is logged at **debug** level and discarded. Stdin stays open, the CLI keeps waiting for input that will never arrive, no result is ever produced, and `query()` blocks forever. There is no error, no timeout, nothing — from the caller's perspective the SDK just stops.

## Mechanism

`Query.stream_input` (`src/claude_agent_sdk/_internal/query.py:829`):

```python
try:
async for message in stream:
if self._closed:
break
await self.transport.write(json.dumps(message) + "\n")

await self.wait_for_result_and_end_input()
except Exception as e:
logger.debug(f"Error streaming input: {e}")
```

On any exception the task exits without calling `end_input()` and without telling anyone. The consumer is blocked in `receive_messages()`; the CLI is blocked on stdin; neither side can make progress.

## Repro (real CLI, SDK 0.2.116, CLI 2.1.207)

Two variants, both verified against the live CLI with a 45s watchdog:

- Generator raises **before yielding anything** → `query()` yields 0 messages and hangs until the watchdog kills it (would hang forever otherwise).
- Generator yields one valid message, first turn completes normally (assistant + result arrive), then raises → `query()` hangs after the healthy-looking turn.

In both cases the only trace of the `ValueError` is an invisible debug log line.

## Suggested fix

Outside teardown (`self._closed`), the failure should: log at error level, close stdin (`end_input()`) so the CLI can wind down, and push an `{"type": "error"}` message into the message stream — the same mechanism `_read_messages` already uses — so `receive_messages()` raises promptly.

PR incoming with this fix + a regression test (fails on main via bounded timeout, passes with the fix). After the fix, both real-CLI repros above raise `Error streaming input: ...` within seconds instead of hanging.

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.