Skip to content

Conversation

roomote[bot]
Copy link

@roomote roomote bot commented Sep 18, 2025

Summary

This PR addresses Issue #8117 by fixing E2BIG errors and preventing mixed system prompts when using the Claude Code API provider.

Problem

Users were experiencing two critical issues with the Claude Code provider:

  1. E2BIG errors on non-Windows systems when custom instructions were large, causing the command arguments to exceed OS limits (~128KiB on Linux)
  2. Mixed system prompts when the system prompt was sent via stdin, causing Claude Code to merge its default prompt with ours instead of replacing it

Solution

The fix implements a consistent approach across all platforms:

  • Always pass the base system prompt via the --system-prompt flag - This ensures Claude Code replaces its default prompt entirely
  • Send only messages via stdin - This keeps argv small to avoid E2BIG errors
  • Remove platform-specific logic - Simplifies the codebase by using the same approach on all operating systems

Changes

  • Modified runProcess function to always use --system-prompt flag for the base system prompt
  • Updated stdin data to only include messages (no longer includes system prompt)
  • Removed Windows-specific branching logic for cleaner, more maintainable code
  • Updated tests to reflect the new consistent behavior across platforms

Testing

  • ✅ All existing tests pass
  • ✅ Updated test suite to verify new behavior
  • ✅ Linting and type checking pass

Impact

This fix ensures:

  • Large custom instructions no longer cause E2BIG errors
  • Claude Code uses exactly the provided system prompt without mixing in defaults
  • Consistent behavior across Windows, macOS, and Linux
  • Improved code maintainability with less platform-specific logic

Fixes #8117


Important

Fixes E2BIG errors and mixed system prompts in Claude Code provider by consistently using --system-prompt flag and sending only messages via stdin.

  • Behavior:
    • runProcess in run.ts now always uses --system-prompt flag for system prompts, preventing mixed prompts.
    • Sends only messages via stdin to avoid E2BIG errors.
    • Removes platform-specific logic for consistent behavior across OS.
  • Testing:
    • Updates tests in run.spec.ts to reflect new behavior, ensuring --system-prompt is always used and only messages are sent via stdin.
    • Tests confirm consistent behavior across Windows and non-Windows systems.
  • Error Handling:
    • Enhances ENOENT error handling with createClaudeCodeNotFoundError() in run.ts for better user guidance.

This description was created by Ellipsis for d4dc2eb. You can customize this summary. It will automatically update as commits are pushed.

…vider

- Always pass base system prompt via --system-prompt flag on all platforms
- Send only messages via stdin to avoid E2BIG errors
- Ensures Claude Code replaces its default prompt instead of merging
- Fixes issues with large custom instructions causing argument size limits

Fixes #8117
@roomote roomote bot requested review from mrubens, cte and jr as code owners September 18, 2025 01:34
@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Sep 18, 2025
Copy link
Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing my own code is like debugging in a mirror - everything looks backwards but the bugs are still mine.

@@ -139,7 +139,7 @@ describe("runClaudeCode", () => {
expect(typeof result[Symbol.asyncIterator]).toBe("function")
})

test("should handle platform-specific stdin behavior", async () => {
test("should always pass system prompt via flag and messages via stdin", async () => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good update to the test name! This now accurately reflects that we're testing consistent behavior across all platforms rather than platform-specific behavior.

args.push("--system-prompt", systemPrompt)
}
// Build args - always pass system prompt as flag to avoid mixing with Claude Code's default
const args = ["-p", "--system-prompt", systemPrompt]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we expand this comment to be more explicit about the dual purpose? Something like:

Suggested change
const args = ["-p", "--system-prompt", systemPrompt]
// Build args - always pass system prompt as flag to ensure Claude Code replaces its default prompt entirely
// (avoids mixing prompts) while keeping argv small by sending messages via stdin (avoids E2BIG)

stdinData = JSON.stringify(messages)
}
// Prepare stdin data: only send messages to avoid E2BIG errors
// System prompt is now always passed via --system-prompt flag
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great simplification! These comments clearly explain the rationale. Is the os import on line 7 still needed now that we've removed the platform-specific logic?

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:M This PR changes 30-99 lines, ignoring generated files.
Projects
Status: Triage
Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Claude Code: Prevent E2BIG + avoid mixed system prompts
2 participants