anthropics / anthropics/claude-agent-sdk-python

system_prompt over 131,071 bytes dies with 'Argument list too long' before any API request

Aberta
#1,096 1 comentário 0 reações 0 responsáveis Ver no GitHub
bug documentation enhancement good first issue
Linguagem predominante
Python
Estrelas
8.1k
Forks
1.3k
Merge médio
2d 31min
PRs com merge (30d)
1

Descrição

## Symptom

A `system_prompt` string of 131,072 bytes or more kills the CLI subprocess before any API request is made:

```
claude_agent_sdk._errors.CLIConnectionError: Failed to start Claude Code: [Errno 7] Argument list too long: ''
```

131,071 bytes spawns fine. 131,072 fails. Reproduces on every CLI version tested.

## Mechanism

`src/claude_agent_sdk/_internal/transport/subprocess_cli.py:291` passes the prompt as a single argv element:

```python
elif isinstance(self._options.system_prompt, str):
cmd.extend(["--system-prompt", self._options.system_prompt])
```

Linux caps a *single* argv element at `MAX_ARG_STRLEN` = `32 × PAGE_SIZE` = 131,072 bytes. This is a per-element limit, distinct from `ARG_MAX`, and is not raisable via `ulimit`.

Reproduced directly, independent of the SDK:

```python
import subprocess, os
os.sysconf('SC_PAGE_SIZE') # 4096
subprocess.run(['/bin/true', 'x'*131071]) # OK
subprocess.run(['/bin/true', 'x'*131072]) # OSError errno 7, Argument list too long
```

The failure is in `execve`, so it precedes anything the CLI or the API would do with the prompt.

## There is a working escape hatch

```python
system_prompt={"type": "file", "path": "/path/to/prompt.txt"}
```

which routes to `--system-prompt-file` (`subprocess_cli.py:295`). Verified with a 200 KB prompt and a ~1 MiB prompt.

This shipped for #267 ("Allow passing system prompts as files", closed). That issue reported the same `Argument list too long` traceback; the feature landed and closed it.

## So what's left

The escape hatch exists but nothing points you at it. A caller who passes a long `str` still gets a raw `OSError` wrapped in `CLIConnectionError`, naming the CLI path and nothing else — no mention of `system_prompt`, of a size limit, or of the file form that would fix it. Diagnosing it requires knowing about `MAX_ARG_STRLEN`.

This is arguably a docs fix plus a clearer error, not a code fix. Options, cheapest first:

1. **Actionable error.** In `_build_command`, check `len(system_prompt.encode())` against the threshold and raise something that names `system_prompt`, the measured size, the limit, and `{"type": "file", "path": ...}`.
2. **Auto-spill.** Above the threshold, write the prompt to a temp file and pass `--system-prompt-file` transparently. Silently correct, but adds temp-file lifetime management.
3. **Docs.** Note the limit and the file form wherever `system_prompt` is documented.

(1) + (3) seems right. (2) is defensible but hides a real platform constraint.

The exact threshold is platform-dependent (`32 * os.sysconf('SC_PAGE_SIZE')`); hardcoding 131072 is wrong on a non-4 KiB-page system, and the limit does not exist at all on Windows.

## Separately: the SDK inherits `os.environ` minus one var

`subprocess_cli.py:491`:

```python
inherited_env = {k: v for k, v in os.environ.items() if k != "CLAUDECODE"}
```

Only `CLAUDECODE` is filtered. So an SDK process launched from inside a coordinator-mode CLI silently inherits `CLAUDE_CODE_COORDINATOR_MODE=1` (a real CLI env var — it gates `isCoordinatorMode()`), which shrinks the injected agent/skill/MCP block and changes caching behavior.

This is surprising: the SDK is a separate agent, and nothing about the parent's coordinator mode should follow it. Worth either documenting or adding to the filter alongside `CLAUDECODE` (see #573, which is why `CLAUDECODE` is filtered in the first place).

## Severity

Low-to-moderate. **There is a working workaround**, and it is already the documented-by-existence API. The cost is diagnosis time: the error names neither the cause nor the cure.

## Not verified

- The 131,071/131,072 boundary I re-measured myself, on Linux, `PAGE_SIZE` 4096, against `/bin/true`. The `CLIConnectionError` traceback and the 200 KB / 1 MiB `--system-prompt-file` successes are from the originating investigation; I did not re-run them.
- The "~19×" shrink figure originally reported for the coordinator-mode block is **not** re-verified and is omitted above. What I did confirm: the SDK inherits everything but `CLAUDECODE` (`subprocess_cli.py:491`), and `CLAUDE_CODE_COORDINATOR_MODE` is read by the CLI (`src/coordinator/coordinatorMode.ts:48` in `claude-cli-internal`).
- Not tested on macOS or Windows.

## Related

- #267 — the original report; closed by adding `--system-prompt-file`. This issue covers what that left behind: the opaque error and the missing docs.
- #573 — why `CLAUDECODE` is filtered from the inherited env.

Guia de contribuição

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

Direção de pesquisa

Start in src/claude_agent_sdk/_internal/transport/subprocess_cli.py at _build_command and the system_prompt branches around lines 291-295. Check how CLIConnectionError wraps subprocess startup failures, then inspect the existing system_prompt documentation and #267 for the file form. Done means oversized string prompts produce an actionable error or documented guidance, with tests covering the limit and workaround; treat the coordinator-mode environment question separately with #573.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
linux, python
Domínio
cli, developer-experience, documentation
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Pouca atividade
Clareza
Razoavelmente clara
Facilidade para iniciantes
55/100

Receba novas issues na sua caixa de entrada

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