From 1b274b081d4f1819df244cdae9d45062dde54a2f Mon Sep 17 00:00:00 2001 From: Gaurav <39389231+gsquared94@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:27:55 -0800 Subject: [PATCH] fix(core): prioritize detailed error messages for code assist setup (#17852) --- .../cli/src/ui/utils/clipboardUtils.test.ts | 3 ++ packages/core/src/code_assist/setup.test.ts | 26 +++++++++++++++++ packages/core/src/code_assist/setup.ts | 29 ++++++++++++++----- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/ui/utils/clipboardUtils.test.ts b/packages/cli/src/ui/utils/clipboardUtils.test.ts index 76eb0bcac3..9dc290be21 100644 --- a/packages/cli/src/ui/utils/clipboardUtils.test.ts +++ b/packages/cli/src/ui/utils/clipboardUtils.test.ts @@ -305,6 +305,9 @@ describe('clipboardUtils', () => { }); it('should return null if tool is not yet detected', async () => { + // Unset session type to ensure no tool is detected automatically + delete process.env['XDG_SESSION_TYPE']; + // Don't prime the tool const result = await clipboardUtils.saveClipboardImage(mockTargetDir); expect(result).toBe(null); diff --git a/packages/core/src/code_assist/setup.test.ts b/packages/core/src/code_assist/setup.test.ts index 0d71a4d162..e1c43ef6e6 100644 --- a/packages/core/src/code_assist/setup.test.ts +++ b/packages/core/src/code_assist/setup.test.ts @@ -312,6 +312,32 @@ describe('setupUser for new user', () => { userTierName: 'paid', }); }); + + it('should throw ineligible tier error when onboarding fails and ineligible tiers exist', async () => { + vi.stubEnv('GOOGLE_CLOUD_PROJECT', ''); + mockLoad.mockResolvedValue({ + allowedTiers: [mockPaidTier], + ineligibleTiers: [ + { + reasonCode: 'UNSUPPORTED_LOCATION', + reasonMessage: + 'Your current account is not eligible for Gemini Code Assist for individuals because it is not currently available in your location.', + tierId: 'free-tier', + tierName: 'Gemini Code Assist for individuals', + }, + ], + }); + mockOnboardUser.mockResolvedValue({ + done: true, + response: { + cloudaicompanionProject: {}, + }, + }); + + await expect(setupUser({} as OAuth2Client)).rejects.toThrow( + 'Your current account is not eligible for Gemini Code Assist for individuals because it is not currently available in your location.', + ); + }); }); describe('setupUser validation', () => { diff --git a/packages/core/src/code_assist/setup.ts b/packages/core/src/code_assist/setup.ts index bf948f1f93..dcd0210de7 100644 --- a/packages/core/src/code_assist/setup.ts +++ b/packages/core/src/code_assist/setup.ts @@ -7,6 +7,7 @@ import type { ClientMetadata, GeminiUserTier, + IneligibleTier, LoadCodeAssistResponse, OnboardUserRequest, } from './types.js'; @@ -35,6 +36,16 @@ export class ValidationCancelledError extends Error { } } +export class IneligibleTierError extends Error { + readonly ineligibleTiers: IneligibleTier[]; + + constructor(ineligibleTiers: IneligibleTier[]) { + const reasons = ineligibleTiers.map((t) => t.reasonMessage).join(', '); + super(reasons); + this.ineligibleTiers = ineligibleTiers; + } +} + export interface UserData { projectId: string; userTier: UserTierId; @@ -127,13 +138,7 @@ export async function setupUser( } // If user is not setup for standard tier, inform them about all other tiers they are ineligible for. - if (loadRes.ineligibleTiers && loadRes.ineligibleTiers.length > 0) { - const reasons = loadRes.ineligibleTiers - .map((t) => t.reasonMessage) - .join(', '); - throw new Error(reasons); - } - throw new ProjectIdRequiredError(); + throwIneligibleOrProjectIdError(loadRes); } return { projectId: loadRes.cloudaicompanionProject, @@ -180,7 +185,8 @@ export async function setupUser( userTierName: tier.name, }; } - throw new ProjectIdRequiredError(); + + throwIneligibleOrProjectIdError(loadRes); } return { @@ -190,6 +196,13 @@ export async function setupUser( }; } +function throwIneligibleOrProjectIdError(res: LoadCodeAssistResponse): never { + if (res.ineligibleTiers && res.ineligibleTiers.length > 0) { + throw new IneligibleTierError(res.ineligibleTiers); + } + throw new ProjectIdRequiredError(); +} + function getOnboardTier(res: LoadCodeAssistResponse): GeminiUserTier { for (const tier of res.allowedTiers || []) { if (tier.isDefault) {