fix(agents): classify Google invalid API keys as auth (#114825)

This commit is contained in:
xin zhuang
2026-07-28 11:26:56 +08:00
committed by GitHub
parent 478a895623
commit 7653bcce58
3 changed files with 60 additions and 0 deletions

View File

@@ -106,6 +106,28 @@ describe("Z.ai vendor error codes (#48988)", () => {
});
});
describe("Google invalid API key errors (#114784)", () => {
it("classifies the Google Generative AI invalid-key response as auth", () => {
const raw =
"Google Generative AI API error (400): API key not valid. Please pass a valid API key. [code=INVALID_ARGUMENT]";
expect(isAuthErrorMessage(raw)).toBe(true);
expect(classifyFailoverReason(raw)).toBe("auth");
});
it("classifies the structured API_KEY_INVALID variant as auth", () => {
expect(isAuthErrorMessage('{"code":"API_KEY_INVALID"}')).toBe(true);
});
it("does not treat unrelated Google invalid arguments as auth", () => {
const raw =
"Google Generative AI API error (400): Request contains an invalid argument. [code=INVALID_ARGUMENT]";
expect(isAuthErrorMessage(raw)).toBe(false);
expect(classifyFailoverReason(raw)).toBeNull();
});
});
describe("Chinese provider overload messages", () => {
const ZHIPU_OVERLOAD = "[1305][该模型当前访问量过大,请您稍后再试]";

View File

@@ -19,6 +19,8 @@ const HIGH_CONFIDENCE_AUTH_PERMANENT_PATTERNS = [
const AMBIGUOUS_AUTH_ERROR_PATTERNS = [
/invalid[_ ]?api[_ ]?key/,
// Google returns HTTP 400 with these variants for an invalid Generative AI key (#114784).
/api[_ ]?key(?:[_ ]?(?:is )?(?:invalid|not valid))\b/i,
/could not (?:authenticate|validate).*(?:api[_ ]?key|credentials)/i,
"permission_error",
] as const satisfies readonly ErrorPattern[];

View File

@@ -1914,6 +1914,42 @@ describe("runWithModelFallback", () => {
expect(result.provider).toBe("anthropic");
});
it("continues to the next model after a Google invalid-key response (#114784)", async () => {
const cfg = makeCfg({
agents: {
defaults: {
model: {
primary: "google/gemini-3.1-pro-preview",
fallbacks: ["anthropic/claude-sonnet-4-6"],
},
},
},
});
const googleInvalidKey = new Error(
"Google Generative AI API error (400): API key not valid. Please pass a valid API key. [code=INVALID_ARGUMENT]",
);
const run = vi
.fn()
.mockRejectedValueOnce(googleInvalidKey)
.mockResolvedValueOnce("fallback ok");
const result = await runWithModelFallback({
cfg,
provider: "google",
model: "gemini-3.1-pro-preview",
run,
});
expect(result.result).toBe("fallback ok");
expect(result.provider).toBe("anthropic");
expect(result.attempts[0]).toMatchObject({
provider: "google",
model: "gemini-3.1-pro-preview",
reason: "auth",
});
expect(run).toHaveBeenCalledTimes(2);
});
it("keeps provider failover metadata authoritative over nested session locks", async () => {
const cfg = makeCfg({
agents: {