From 9248881d42d02764751c7e9ca14afd26511a187e Mon Sep 17 00:00:00 2001 From: Jayakrishnan Date: Tue, 10 Mar 2026 12:01:46 +0000 Subject: [PATCH] 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 --- packages/adapter-utils/src/server-utils.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/adapter-utils/src/server-utils.ts b/packages/adapter-utils/src/server-utils.ts index 3d273cd9..8e28fbff 100644 --- a/packages/adapter-utils/src/server-utils.ts +++ b/packages/adapter-utils/src/server-utils.ts @@ -272,7 +272,19 @@ export async function runChildProcess( const onLogError = opts.onLogError ?? ((err, id, msg) => console.warn({ err, runId: id }, msg)); return new Promise((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, {