openclaw - ✅(Solved) Fix bug: claude-cli backend on Windows passes huge system prompt inline, causing spawn ENAMETOOLONG [2 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#71600Fetched 2026-04-26 05:10:51
View on GitHub
Comments
2
Participants
3
Timeline
6
Reactions
0
Author
Timeline (top)
commented ×2cross-referenced ×2closed ×1labeled ×1

On Windows, the claude-cli backend passes the full OpenClaw system prompt as a command-line argument (--append-system-prompt), but the combined prompt exceeds Windows' ~32,767-char command-line limit (~41k+ chars in a typical workspace), causing Node child_process.spawn() to fail with ENAMETOOLONG before Claude Code ever starts.

Error Message

[process/supervisor] spawn failed: reason=Error: spawn ENAMETOOLONG

Root Cause

On Windows, the claude-cli backend passes the full OpenClaw system prompt as a command-line argument (--append-system-prompt), but the combined prompt exceeds Windows' ~32,767-char command-line limit (~41k+ chars in a typical workspace), causing Node child_process.spawn() to fail with ENAMETOOLONG before Claude Code ever starts.

Fix Action

Fix / Workaround

Hot patch: write the system prompt to a temp file and pass --append-system-prompt-file <path> instead of --append-system-prompt. After this patch, a claude-cli/claude-opus-4-7 subagent completed successfully with ~44.7k prompt/cache.

The hot patch (write prompt to temp file, pass --append-system-prompt-file) fully resolves the issue without any other changes needed.

PR fix notes

PR #71617: fix(claude-cli): pass system prompt as file path to avoid Windows ENAMETOOLONG (#71600)

Description (problem / solution / changelog)

Closes #71600.

Bug

On Windows, Claude CLI sessions die with spawn ENAMETOOLONG whenever the OpenClaw-injected system prompt + workspace context exceeds the ~32,767-character argv limit. Reporter saw this at ~41k chars in a typical workspace — completely deterministic for Windows users with non-trivial workspace context. Linux/macOS don't impose this OS-level limit so the bug is Windows-specific.

Reporter verified hot patch: write the prompt to a temp file and pass --append-system-prompt-file <path> instead of --append-system-prompt. Resumed 44.7k-prompt sessions immediately.

Fix

Claude Code CLI 2.x already supports the file-based counterpart --append-system-prompt-file <path>. OpenClaw already had a temp-file writer (writeCliSystemPromptFile) for the Codex-style TOML-config-override path. This PR generalizes it for Claude's flag-pair shape:

  • src/config/types.agent-defaults.ts — add systemPromptFileArg to CliBackendConfig. Documented as the file-arg sibling of existing systemPromptArg (inline) and systemPromptFileConfigKey (TOML).
  • src/agents/cli-runner/helpers.ts
    • writeCliSystemPromptFile: write temp file when EITHER systemPromptFileArg OR systemPromptFileConfigKey is set.
    • buildCliArgs: new branch that prefers the file-arg pair (flag, path) over inline arg / TOML override when set + file path present. Falls back to inline systemPromptArg if no file path (defense-in-depth so the prompt is never silently dropped on file-write failure).
  • extensions/anthropic/cli-backend.ts — wire systemPromptFileArg: \"--append-system-prompt-file\".

This is also a strict improvement on macOS/Linux: writing the prompt to a file avoids re-encoding the same large string on every spawn and keeps it out of process listings (ps aux no longer shows the full prompt). No behavior change for Codex (still uses TOML override), Gemini (still inline), or any backend that doesn't set systemPromptFileArg.

Tests

  • new buildCliArgs case: --append-system-prompt-file flag emitted when configured + file path available.
  • new buildCliArgs case: falls back to inline arg when file path missing (defense-in-depth).
  • new writeCliSystemPromptFile case: temp file written when only systemPromptFileArg is set (Claude CLI shape).
  • new writeCliSystemPromptFile case: returns no path when neither file mechanism is configured (Gemini shape).

22 tests pass. Lint clean (pnpm oxlint — 0 warnings, 0 errors).

🤖 generated with assistance from Claude Code Co-authored-by: HCL [email protected]

Changed files

  • extensions/anthropic/cli-backend.ts (modified, +6/-0)
  • src/agents/cli-runner.helpers.test.ts (modified, +68/-0)
  • src/agents/cli-runner/helpers.ts (modified, +20/-1)
  • src/config/types.agent-defaults.ts (modified, +10/-0)

PR #71626: test(cli-runner): bound argv length for large Claude system prompts (#71600)

Description (problem / solution / changelog)

Why

f7b71abf48 ("fix(agents): pass Claude system prompt via file") routes the Claude CLI system prompt through --append-system-prompt-file <path> whenever the backend exposes systemPromptFileArg. That fix unblocks the Windows-specific spawn ENAMETOOLONG reported in #71600, where workspace-scale system prompts (~41k chars) blow past Windows' CreateProcessW MAX_COMMAND_LINE limit (~32,767 chars).

Existing coverage in cli-runner.spawn.test.ts ("passes Claude system prompts through a file instead of argv") asserts the file path appears in argv and the prompt body doesn't, but uses a small hardcoded prompt. It doesn't pin the actual regression target — the argv length staying under Windows' OS limit when the prompt is workspace-scale.

What this adds

A focused regression test in src/agents/cli-runner.system-prompt-argv-bound.test.ts:

  1. Length bound: with a 40k-char system prompt, the joined argv reaching the supervisor stays under 32,767 chars.
  2. Defense-in-depth: the prompt body itself (BEGIN-PROMPT-MARKER/END-PROMPT-MARKER sentinels) never appears anywhere in argv.

This way, a future change that bypasses the file path — even one where argv length stays bounded by accident (truncation, placeholder substitution) — will still fail (2).

Verified

Locally flipped the test backend config from systemPromptFileArg: "--append-system-prompt-file" to systemPromptArg: "--append-system-prompt" (simulating the pre-fix state). Both cases fail under the broken config: the runtime falls back to inlining the prompt and argv blows past the 32k threshold. Restoring the file arg returns both cases to green.

Pure test addition; no production code change. No changelog entry.

Verification

  • pnpm test src/agents/cli-runner.system-prompt-argv-bound.test.ts → 2/2 pass
  • pnpm format + pnpm lint → clean on the touched file
  • Doesn't affect #71600 itself; the fix is already on main from f7b71abf48 and will land in the next release. This locks the bound so it can't quietly regress again.

Changed files

  • src/agents/cli-runner.system-prompt-argv-bound.test.ts (added, +168/-0)

Code Example

systemPromptArg: "--append-system-prompt",
systemPromptMode: "append",
systemPromptWhen: "first",

---
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

No

Summary

On Windows, the claude-cli backend passes the full OpenClaw system prompt as a command-line argument (--append-system-prompt), but the combined prompt exceeds Windows' ~32,767-char command-line limit (~41k+ chars in a typical workspace), causing Node child_process.spawn() to fail with ENAMETOOLONG before Claude Code ever starts.

Steps to reproduce

  1. Install OpenClaw 2026.4.23 on Windows 11 with Claude Code CLI 2.1.119.
  2. Configure a claude-cli/claude-opus-4-7 provider with workspace context files totalling >30k chars.
  3. Start a Telegram or direct session that triggers a claude-cli subagent.
  4. Observe the session fail immediately with spawn ENAMETOOLONG in the gateway logs.

Expected behavior

The claude-cli subagent should start successfully and complete the session, as it does on macOS/Linux where command-line length is not an OS-level constraint.

Actual behavior

Sessions immediately fail with:

[agent/cli-backend] cli exec: provider=claude-cli model=opus promptChars=... [process/supervisor] spawn failed: reason=Error: spawn ENAMETOOLONG Embedded agent failed before reply: spawn ENAMETOOLONG

No reply is sent. Running claude -p "hello" --output-format stream-json --verbose directly from the shell works fine, so the failure is specific to OpenClaw's inline argument passing.

OpenClaw version

2026.4.23 (a979721)

Operating system

Windows 11

Install method

npm global

Model

claude-cli/claude-opus-4-7

Provider / routing chain

openclaw -> claude-cli (Claude Code CLI 2.1.119) -> claude-opus-4-7

Additional provider/model setup details

The generated runtime backend config contains:

systemPromptArg: "--append-system-prompt",
systemPromptMode: "append",
systemPromptWhen: "first",

This causes OpenClaw to pass the full system prompt inline as a CLI argument. The injected workspace context alone was ~41,029 chars, which combined with OpenClaw's own system instructions, tool schema, runtime metadata, and channel context blows past Windows' hard ~32,767-char command-line limit.

Hot patch: write the system prompt to a temp file and pass --append-system-prompt-file <path> instead of --append-system-prompt. After this patch, a claude-cli/claude-opus-4-7 subagent completed successfully with ~44.7k prompt/cache.

Claude Code CLI already supports file-based variants:

  • --append-system-prompt-file <path>
  • --system-prompt-file <path>

Suggested fix: for the claude-cli backend, prefer file-based prompt passing (--append-system-prompt-file) instead of inline passing, at minimum on Windows or whenever the system prompt exceeds a safe command-line length threshold.

Logs, screenshots, and evidence

Impact and severity

  • Affected: All Windows users running the claude-cli backend with any non-trivial workspace context
  • Severity: Critical – blocks all claude-cli/claude-opus-4-7 (and similar) sessions entirely; no fallback or partial operation
  • Frequency: Always, deterministic once the combined prompt length exceeds ~32k chars
  • Consequence: No AI responses are generated; sessions silently fail from the user's perspective

Additional information

Node version: v24.13.1 Claude Code CLI version: 2.1.119

This is a Windows-specific regression since Windows has a hard OS-level limit on command-line length (~32,767 chars total) whereas macOS and Linux do not impose this restriction in practice.

The hot patch (write prompt to temp file, pass --append-system-prompt-file) fully resolves the issue without any other changes needed.

extent analysis

TL;DR

Prefer file-based prompt passing using --append-system-prompt-file instead of inline passing to avoid exceeding Windows' command-line length limit.

Guidance

  • Identify the system prompt length and check if it exceeds the safe command-line length threshold (~32,767 chars) on Windows.
  • Modify the claude-cli backend to use file-based prompt passing (--append-system-prompt-file) when the system prompt length exceeds the threshold.
  • Verify that the --append-system-prompt-file option is supported by the Claude Code CLI version being used (in this case, version 2.1.119).
  • Test the modified backend with a workspace context that previously exceeded the command-line length limit to ensure successful session completion.

Example

No code snippet is provided as the necessary changes are configuration-based and depend on the specific implementation of the claude-cli backend.

Notes

This solution is specific to Windows due to its command-line length limit and may not be necessary on other operating systems like macOS and Linux.

Recommendation

Apply the workaround by modifying the claude-cli backend to prefer file-based prompt passing using --append-system-prompt-file to avoid the command-line length limit issue on Windows. This approach is already supported by the Claude Code CLI and has been successfully tested with a hot patch.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The claude-cli subagent should start successfully and complete the session, as it does on macOS/Linux where command-line length is not an OS-level constraint.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix bug: claude-cli backend on Windows passes huge system prompt inline, causing spawn ENAMETOOLONG [2 pull requests, 2 comments, 3 participants]