mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 18:01:35 +00:00
fix(agents): classify Google invalid API keys as auth (#114825)
This commit is contained in:
@@ -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][该模型当前访问量过大,请您稍后再试]";
|
||||
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user