anthropics / anthropics/claude-agent-sdk-python

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

Abierto
#1,108 0 comentarios 0 reacciones 0 asignados Ver en GitHub
bug
Lenguaje dominante
Python
Estrellas
8.1k
Forks
1.3k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

## 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.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.