mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-23 19:08:22 -06:00
fix: Google invalid keys no longer stop model fallback (#114887)
* fix(agents): classify Google invalid API keys Fixes #114784.\n\nCo-authored-by: 1052326311 <65798732+1052326311@users.noreply.github.com> * fix(agents): bound invalid key matcher
This commit is contained in:
committed by
GitHub
parent
add9205d1a
commit
f99d45cb55
@@ -107,7 +107,7 @@ 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", () => {
|
||||
it("classifies Google Generative AI's 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]";
|
||||
|
||||
@@ -115,8 +115,14 @@ describe("Google invalid API key errors (#114784)", () => {
|
||||
expect(classifyFailoverReason(raw)).toBe("auth");
|
||||
});
|
||||
|
||||
it("classifies the structured API_KEY_INVALID variant as auth", () => {
|
||||
expect(isAuthErrorMessage('{"code":"API_KEY_INVALID"}')).toBe(true);
|
||||
it.each([
|
||||
"invalid_api_key_error",
|
||||
"API key is invalid",
|
||||
'{"code":"API_KEY_INVALID"}',
|
||||
'{"code":"API_KEY_INVALID_ERROR"}',
|
||||
])("classifies the %s variant as auth", (raw) => {
|
||||
expect(isAuthErrorMessage(raw)).toBe(true);
|
||||
expect(classifyFailoverReason(raw)).toBe("auth");
|
||||
});
|
||||
|
||||
it("does not treat unrelated Google invalid arguments as auth", () => {
|
||||
@@ -125,9 +131,10 @@ describe("Google invalid API key errors (#114784)", () => {
|
||||
|
||||
expect(isAuthErrorMessage(raw)).toBe(false);
|
||||
expect(classifyFailoverReason(raw)).toBeNull();
|
||||
expect(isAuthErrorMessage("API key invalidation policy updated")).toBe(false);
|
||||
expect(isAuthErrorMessage("INVALID API KEYSTORE configuration")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Chinese provider overload messages", () => {
|
||||
const ZHIPU_OVERLOAD = "[1305][该模型当前访问量过大,请您稍后再试]";
|
||||
|
||||
|
||||
@@ -17,10 +17,13 @@ const HIGH_CONFIDENCE_AUTH_PERMANENT_PATTERNS = [
|
||||
"not allowed for this organization",
|
||||
] as const satisfies readonly ErrorPattern[];
|
||||
|
||||
// Providers use both "invalid API key" and "API key is/not valid" word order.
|
||||
// Keep them in one matcher so every result/exception classifier agrees on auth failover.
|
||||
const INVALID_API_KEY_RE =
|
||||
/(?:invalid[_ ]?api[_ ]?key(?![a-z0-9])|api[_ ]?key(?:[_ ]?(?:is[_ ]?)?(?:invalid(?![a-z0-9])|not[_ ]?valid(?![a-z0-9]))))/i;
|
||||
|
||||
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,
|
||||
INVALID_API_KEY_RE,
|
||||
/could not (?:authenticate|validate).*(?:api[_ ]?key|credentials)/i,
|
||||
"permission_error",
|
||||
] as const satisfies readonly ErrorPattern[];
|
||||
|
||||
@@ -50,6 +50,27 @@ describe("classifyEmbeddedAgentRunResultForModelFallback", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies Google invalid-key result payloads before fallback settlement", () => {
|
||||
const rawError =
|
||||
"Google Generative AI API error (400): API key not valid. Please pass a valid API key. [code=INVALID_ARGUMENT]";
|
||||
|
||||
const result = classifyEmbeddedAgentRunResultForModelFallback({
|
||||
provider: "google",
|
||||
model: "gemini-3.1-pro-preview",
|
||||
result: {
|
||||
payloads: [{ isError: true, text: rawError }],
|
||||
meta: { durationMs: 42 },
|
||||
},
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
message: `google/gemini-3.1-pro-preview ended with a provider error: ${rawError}`,
|
||||
reason: "auth",
|
||||
code: "embedded_error_payload",
|
||||
rawError,
|
||||
});
|
||||
});
|
||||
|
||||
it("classifies structured provider upstream_error payloads as fallback-worthy", () => {
|
||||
const rawError =
|
||||
'{"error":{"message":"Upstream request failed","type":"upstream_error","param":"","code":null}}';
|
||||
|
||||
Reference in New Issue
Block a user