From 1fd2fb83fbf08ef9ef9a03fb69d9c6cea5f8eb37 Mon Sep 17 00:00:00 2001 From: Wooseong Kim Date: Tue, 21 Apr 2026 16:52:19 +0900 Subject: [PATCH] fix(runtime): strip reintroduced Anthropic routing env Prevent settings-profile Claude launches from reintroducing routing/auth env after the final env merge. - re-strip ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, and ANTHROPIC_API_KEY after merging envVars - preserve model-selection env such as ANTHROPIC_MODEL and ANTHROPIC_DEFAULT_SONNET_MODEL - add a regression test covering explicit settings-profile overrides that try to reintroduce routing env Verification: - bun test tests/unit/utils/claudecode-env-stripping.test.ts - bun run validate --- src/utils/shell-executor.ts | 5 ++++- .../utils/claudecode-env-stripping.test.ts | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/utils/shell-executor.ts b/src/utils/shell-executor.ts index 3764f484..e6183349 100644 --- a/src/utils/shell-executor.ts +++ b/src/utils/shell-executor.ts @@ -177,10 +177,13 @@ export function execClaude( const mergedEnv = envVars ? { ...baseEnv, ...claudeLaunchEnv, ...envVars, ...webSearchEnv } : { ...baseEnv, ...claudeLaunchEnv, ...webSearchEnv }; + const effectiveMergedEnv = stripInheritedAnthropicRoutingEnv + ? stripAnthropicRoutingEnv(mergedEnv) + : mergedEnv; // Strip Claude Code nested session guard env var to allow CCS delegation // (Claude Code v2.1.39+ sets CLAUDECODE to detect nested sessions) - const env = stripClaudeCodeEnv(mergedEnv); + const env = stripClaudeCodeEnv(effectiveMergedEnv); if (profileType !== 'account') { try { diff --git a/tests/unit/utils/claudecode-env-stripping.test.ts b/tests/unit/utils/claudecode-env-stripping.test.ts index 96ca54df..afed6472 100644 --- a/tests/unit/utils/claudecode-env-stripping.test.ts +++ b/tests/unit/utils/claudecode-env-stripping.test.ts @@ -367,6 +367,26 @@ describe('CLAUDECODE environment stripping', () => { expect(env.ANTHROPIC_SMALL_FAST_MODEL).toBe('gpt-5-codex-mini'); }); + it('execClaude strips routing env reintroduced by explicit settings-profile overrides', () => { + execClaude('claude', ['--help'], { + CCS_PROFILE_TYPE: 'settings', + CCS_STRIP_INHERITED_ANTHROPIC_ENV: '1', + ANTHROPIC_BASE_URL: 'http://127.0.0.1:8317/api/provider/codex', + ANTHROPIC_AUTH_TOKEN: 'reintroduced-routing-token', + ANTHROPIC_API_KEY: 'reintroduced-api-key', + ANTHROPIC_MODEL: 'gpt-5.4', + ANTHROPIC_DEFAULT_SONNET_MODEL: 'gpt-5.4', + }); + + expect(spawnCalls.length).toBeGreaterThan(0); + const env = spawnCalls[0].options?.env as NodeJS.ProcessEnv; + expect(env.ANTHROPIC_BASE_URL).toBeUndefined(); + expect(env.ANTHROPIC_AUTH_TOKEN).toBeUndefined(); + expect(env.ANTHROPIC_API_KEY).toBeUndefined(); + expect(env.ANTHROPIC_MODEL).toBe('gpt-5.4'); + expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('gpt-5.4'); + }); + it('headless executor spawn path strips CLAUDECODE before spawn', async () => { writeConfigWithAutoUpdatePreference(false); process.env.CLAUDECODE = 'nested';