diff --git a/src/commands/onboard-github/onboard-github.test.ts b/src/commands/onboard-github/onboard-github.test.ts index 4177433ca..56ec5e8e2 100644 --- a/src/commands/onboard-github/onboard-github.test.ts +++ b/src/commands/onboard-github/onboard-github.test.ts @@ -97,6 +97,7 @@ describe('onboarding auth precedence cleanup', () => { GITHUB_ENTERPRISE_URL: 'https://github.old.example.com', CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED: '1', CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED_ID: 'profile_old', + CLAUDE_CODE_USE_GEMINI_VERTEX: '1', } applyGithubOnboardingProcessEnv('github:copilot', undefined, env) @@ -115,6 +116,9 @@ describe('onboarding auth precedence cleanup', () => { expect(env.GITHUB_ENTERPRISE_URL).toBeUndefined() expect(env.CLAUDE_CODE_USE_OPENAI).toBeUndefined() + // The fast path must clear Gemini Vertex routing too, like the + // device-flow finalize path (PROVIDER_SPECIFIC_KEYS). + expect(env.CLAUDE_CODE_USE_GEMINI_VERTEX).toBeUndefined() expect(env.CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED).toBeUndefined() expect(env.CLAUDE_CODE_PROVIDER_PROFILE_ENV_APPLIED_ID).toBeUndefined() @@ -127,6 +131,7 @@ describe('onboarding auth precedence cleanup', () => { expect(settingsEnv.OPENAI_PROJECT).toBeUndefined() expect(settingsEnv.OPENAI_ORGANIZATION).toBeUndefined() expect(settingsEnv.GITHUB_ENTERPRISE_URL).toBeUndefined() + expect(settingsEnv.CLAUDE_CODE_USE_GEMINI_VERTEX).toBeUndefined() }) test('persists Enterprise URL when switching to GitHub Enterprise', () => { diff --git a/src/commands/onboard-github/onboard-github.tsx b/src/commands/onboard-github/onboard-github.tsx index 670584fc9..24a961f90 100644 --- a/src/commands/onboard-github/onboard-github.tsx +++ b/src/commands/onboard-github/onboard-github.tsx @@ -114,6 +114,7 @@ export function buildGithubOnboardingSettingsEnv( OPENAI_API_BASE: undefined, CLAUDE_CODE_USE_OPENAI: undefined, CLAUDE_CODE_USE_GEMINI: undefined, + CLAUDE_CODE_USE_GEMINI_VERTEX: undefined, CLAUDE_CODE_USE_BEDROCK: undefined, CLAUDE_CODE_USE_VERTEX: undefined, CLAUDE_CODE_USE_FOUNDRY: undefined, @@ -144,6 +145,7 @@ export function applyGithubOnboardingProcessEnv( delete env.CLAUDE_CODE_USE_OPENAI delete env.CLAUDE_CODE_USE_GEMINI + delete env.CLAUDE_CODE_USE_GEMINI_VERTEX delete env.CLAUDE_CODE_USE_BEDROCK delete env.CLAUDE_CODE_USE_VERTEX delete env.CLAUDE_CODE_USE_FOUNDRY diff --git a/src/utils/messages.ts b/src/utils/messages.ts index c7f6c3869..345077085 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -770,6 +770,13 @@ export function normalizeMessages(messages: Message[]): NormalizedMessage[] { // and remains true for all subsequent messages in the normalization process. let isNewChain = false return messages.flatMap(message => { + // Defensive: a falsy slot (sparse array) or a non-object would throw on + // the message.type read below. Drop it — this mirrors the default arm + // and keeps the render pipeline alive instead of crashing the UI. + if (!message || typeof message !== 'object' || !('type' in message)) { + return [] + } + switch (message.type) { case 'assistant': { isNewChain = isNewChain || message.message.content.length > 1 diff --git a/src/utils/providerFlag.test.ts b/src/utils/providerFlag.test.ts index 245bf4fa3..663a559c7 100644 --- a/src/utils/providerFlag.test.ts +++ b/src/utils/providerFlag.test.ts @@ -17,6 +17,7 @@ import { const ENV_KEYS = [ 'CLAUDE_CODE_USE_OPENAI', 'CLAUDE_CODE_USE_GEMINI', + 'CLAUDE_CODE_USE_GEMINI_VERTEX', 'CLAUDE_CODE_USE_GITHUB', 'CLAUDE_CODE_USE_MISTRAL', 'CLAUDE_CODE_USE_BEDROCK', @@ -26,6 +27,7 @@ const ENV_KEYS = [ 'OPENAI_API_KEY', 'OPENAI_MODEL', 'GEMINI_MODEL', + 'GEMINI_VERTEX_MODEL', 'NVIDIA_API_KEY', 'NVIDIA_NIM', 'BNKR_API_KEY', @@ -53,6 +55,7 @@ beforeEach(async () => { const RESET_KEYS = [ 'CLAUDE_CODE_USE_OPENAI', 'CLAUDE_CODE_USE_GEMINI', + 'CLAUDE_CODE_USE_GEMINI_VERTEX', 'CLAUDE_CODE_USE_GITHUB', 'CLAUDE_CODE_USE_MISTRAL', 'CLAUDE_CODE_USE_BEDROCK', @@ -62,6 +65,7 @@ const RESET_KEYS = [ 'OPENAI_API_KEY', 'OPENAI_MODEL', 'GEMINI_MODEL', + 'GEMINI_VERTEX_MODEL', 'NVIDIA_API_KEY', 'NVIDIA_NIM', 'BNKR_API_KEY', diff --git a/src/utils/toolUseIds.ts b/src/utils/toolUseIds.ts index a9dd1335d..39e0e30e0 100644 --- a/src/utils/toolUseIds.ts +++ b/src/utils/toolUseIds.ts @@ -34,5 +34,8 @@ export function sanitizeToolUseIdForWire( if (clean.length === 0) { return `tool${tail}` } - return clean.slice(0, maxLength - tail.length) + tail + // Defensive: keep at least one prefix char if a caller ever passes a + // maxLength smaller than the hash tail (all current call sites use >= 40). + const prefixLength = Math.max(1, maxLength - tail.length) + return clean.slice(0, prefixLength) + tail }