fix(adapter-utils): strip Claude Code env vars from child processes
When the Paperclip server is started from within a Claude Code session (e.g. `npx paperclipai run` in a Claude Code terminal), the `CLAUDECODE` and related env vars (`CLAUDE_CODE_ENTRYPOINT`, `CLAUDE_CODE_SESSION`, `CLAUDE_CODE_PARENT_SESSION`) leak into `process.env`. Since `runChildProcess()` spreads `process.env` into the child environment, every spawned `claude` CLI process inherits these vars and immediately exits with: "Claude Code cannot be launched inside another Claude Code session." This is particularly disruptive for the `claude-local` adapter, where every agent run spawns a `claude` child process. A single contaminated server start (or cron job that inherits the env) silently breaks all agent executions until the server is restarted in a clean environment. The fix deletes the four known Claude Code nesting-guard env vars from the merged environment before passing it to `spawn()`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -272,7 +272,19 @@ export async function runChildProcess(
|
||||
const onLogError = opts.onLogError ?? ((err, id, msg) => console.warn({ err, runId: id }, msg));
|
||||
|
||||
return new Promise<RunProcessResult>((resolve, reject) => {
|
||||
const mergedEnv = ensurePathInEnv({ ...process.env, ...opts.env });
|
||||
const rawMerged: NodeJS.ProcessEnv = { ...process.env, ...opts.env };
|
||||
|
||||
// Strip Claude Code nesting-guard env vars so spawned `claude` processes
|
||||
// don't refuse to start with "cannot be launched inside another session".
|
||||
// These vars leak in when the Paperclip server itself is started from
|
||||
// within a Claude Code session (e.g. `npx paperclipai run` in a terminal
|
||||
// owned by Claude Code) or when cron inherits a contaminated shell env.
|
||||
delete rawMerged.CLAUDECODE;
|
||||
delete rawMerged.CLAUDE_CODE_ENTRYPOINT;
|
||||
delete rawMerged.CLAUDE_CODE_SESSION;
|
||||
delete rawMerged.CLAUDE_CODE_PARENT_SESSION;
|
||||
|
||||
const mergedEnv = ensurePathInEnv(rawMerged);
|
||||
void resolveSpawnTarget(command, args, opts.cwd, mergedEnv)
|
||||
.then((target) => {
|
||||
const child = spawn(target.command, target.args, {
|
||||
|
||||
Reference in New Issue
Block a user