diff --git a/packages/cli/src/config/extensions/extensionSettings.test.ts b/packages/cli/src/config/extensions/extensionSettings.test.ts index 539577d915..39b1eafe40 100644 --- a/packages/cli/src/config/extensions/extensionSettings.test.ts +++ b/packages/cli/src/config/extensions/extensionSettings.test.ts @@ -397,6 +397,48 @@ describe('extensionSettings', () => { const actualContent = await fsPromises.readFile(expectedEnvPath, 'utf-8'); expect(actualContent).toBe('VAR1="a value with spaces"\n'); }); + + it('should not attempt to clear secrets if keychain is unavailable', async () => { + // Arrange + const mockIsAvailable = vi.fn().mockResolvedValue(false); + const mockListSecrets = vi.fn(); + + vi.mocked(KeychainTokenStorage).mockImplementation( + () => + ({ + isAvailable: mockIsAvailable, + listSecrets: mockListSecrets, + deleteSecret: vi.fn(), + getSecret: vi.fn(), + setSecret: vi.fn(), + }) as unknown as KeychainTokenStorage, + ); + + const config: ExtensionConfig = { + name: 'test-ext', + version: '1.0.0', + settings: [], // Empty settings triggers clearSettings + }; + + const previousConfig: ExtensionConfig = { + name: 'test-ext', + version: '1.0.0', + settings: [{ name: 's1', description: 'd1', envVar: 'VAR1' }], + }; + + // Act + await maybePromptForSettings( + config, + '12345', + mockRequestSetting, + previousConfig, + undefined, + ); + + // Assert + expect(mockIsAvailable).toHaveBeenCalled(); + expect(mockListSecrets).not.toHaveBeenCalled(); + }); }); describe('promptForSetting', () => { diff --git a/packages/cli/src/config/extensions/extensionSettings.ts b/packages/cli/src/config/extensions/extensionSettings.ts index 1c39ca048b..eb953d19c5 100644 --- a/packages/cli/src/config/extensions/extensionSettings.ts +++ b/packages/cli/src/config/extensions/extensionSettings.ts @@ -289,7 +289,7 @@ async function clearSettings( if (fsSync.existsSync(envFilePath)) { await fs.writeFile(envFilePath, ''); } - if (!keychain.isAvailable()) { + if (!(await keychain.isAvailable())) { return; } const secrets = await keychain.listSecrets();