Fix bug 1: Only fetch Anthropic models when API key exists

getAnthropicModels() was called unconditionally on mount, causing a
console error when no API key was set. Now chains the call after
getAnthropicApiKeyExists() confirms a key is present.

Includes regression test added before the fix per bug workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-02-20 12:01:47 +00:00
parent e12985f40c
commit 3e99929d03
3 changed files with 48 additions and 16 deletions

View File

@@ -0,0 +1,24 @@
---
name: Anthropic models fetched without API key
---
# Bug 1: Anthropic Models Fetched Without API Key
## Symptom
Browser console shows `Error: Anthropic API key not found. Please set your API key.` on every page load, even when the user has no Anthropic API key and is using `claude-code-pty`.
## Root Cause
`Chat.tsx` unconditionally calls `api.getAnthropicModels()` on mount. The server endpoint requires an API key to call the Anthropic models list API. When no key is set, the request fails with an error logged to the console.
## Reproduction Steps
1. Start the server without setting an Anthropic API key
2. Open the web UI
3. Open browser developer console
4. Observe the error on page load
## Proposed Fix
Only call `getAnthropicModels()` after `getAnthropicApiKeyExists()` confirms a key is set. Chain the calls so the models fetch is conditional.

View File

@@ -592,4 +592,17 @@ describe("Chat review panel", () => {
expect(await screen.findByText("Cannot read stories")).toBeInTheDocument(); expect(await screen.findByText("Cannot read stories")).toBeInTheDocument();
}); });
it("does not fetch Anthropic models when no API key exists", async () => {
mockedApi.getAnthropicApiKeyExists.mockResolvedValue(false);
mockedApi.getAnthropicModels.mockClear();
render(<Chat projectPath="/tmp/project" onCloseProject={vi.fn()} />);
await waitFor(() => {
expect(mockedApi.getAnthropicApiKeyExists).toHaveBeenCalled();
});
expect(mockedApi.getAnthropicModels).not.toHaveBeenCalled();
});
}); });

View File

@@ -174,26 +174,21 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) {
.getAnthropicApiKeyExists() .getAnthropicApiKeyExists()
.then((exists) => { .then((exists) => {
setHasAnthropicKey(exists); setHasAnthropicKey(exists);
if (!exists) return;
return api.getAnthropicModels().then((models) => {
if (models.length > 0) {
const sortedModels = models.sort((a, b) =>
a.toLowerCase().localeCompare(b.toLowerCase()),
);
setClaudeModels(sortedModels);
} else {
setClaudeModels([]);
}
});
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);
setHasAnthropicKey(false); setHasAnthropicKey(false);
});
api
.getAnthropicModels()
.then((models) => {
if (models.length > 0) {
const sortedModels = models.sort((a, b) =>
a.toLowerCase().localeCompare(b.toLowerCase()),
);
setClaudeModels(sortedModels);
} else {
setClaudeModels([]);
}
})
.catch((err) => {
console.error(err);
setClaudeModels([]); setClaudeModels([]);
}); });
}, []); }, []);