diff --git a/packages/ai/src/provider-error.ts b/packages/ai/src/provider-error.ts index 35b9cff7425..9da65eaf270 100644 --- a/packages/ai/src/provider-error.ts +++ b/packages/ai/src/provider-error.ts @@ -114,7 +114,8 @@ const QUOTA_CODES = new Set([ "creditlimitexceeded", ]) // Google reports an invalid API key as HTTP 400 INVALID_ARGUMENT with this `details[].reason`. -const AUTH_CODES = new Set(["authentication_error", "permission_error", "api_key_invalid"]) +// Z.ai's Responses API reports account and plan rejections mid-stream as `permission_denied`. +const AUTH_CODES = new Set(["authentication_error", "permission_error", "permission_denied", "api_key_invalid"]) const SERVER_CODES = new Set([ "api_error", "internal_error", @@ -128,6 +129,7 @@ const SERVER_CODES = new Set([ ]) // `invalid_request` is the Vercel AI Gateway's code for an upstream request rejection. const INVALID_REQUEST_CODES = new Set([ + "model_not_found", "invalid_prompt", "invalid_request", "invalid_request_error", diff --git a/packages/ai/test/provider-error.test.ts b/packages/ai/test/provider-error.test.ts index 98a94c1b143..8e4b00ef45e 100644 --- a/packages/ai/test/provider-error.test.ts +++ b/packages/ai/test/provider-error.test.ts @@ -422,6 +422,19 @@ describe("provider error rawBody classification", () => { expect( classifyProviderFailure({ message: "Request failed", rawBody: '{"error":{"code":"insufficient_quota"}}' })._tag, ).toBe("QuotaExceeded") + // Z.ai Responses stream rejections + expect( + classifyProviderFailure({ + message: "Unknown Model, please check the model code.", + rawBody: '{"type":"response.failed","response":{"error":{"code":"model_not_found"}}}', + })._tag, + ).toBe("InvalidRequest") + expect( + classifyProviderFailure({ + message: "Your GLM Coding Plan package has expired and is temporarily unavailable.", + rawBody: '{"type":"response.failed","response":{"error":{"code":"permission_denied"}}}', + })._tag, + ).toBe("Authentication") }) })