{"record":{"id":"e6470b6e68e1ba64","repo":"can1357/oh-my-pi","slug":"z-ai-operation-failed-envelope-msg-code","errorCode":null,"errorMessage":"Z.ai ${operation} failed: ${envelope.msg ?? `code ${String(envelope.code)}`}","messagePattern":"Z\\.ai (.+?) failed: (.+?)`\\}","errorType":"exception","errorClass":"AIError.OAuthError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/registry/oauth/zai.ts","lineNumber":59,"sourceCode":"\n/**\n * Z.ai's `{ code, msg, data, success }` envelope. The OAuth token endpoint\n * signals success with `code: 0`; the biz endpoints (`api.z.ai`) use\n * `code: 200` / `success: true`. Accept both; throw `msg` on failure. Bodies\n * without a status wrapper pass through unchanged.\n */\nfunction isSuccessCode(code: unknown): boolean {\n\tif (code == null) return true;\n\tif (typeof code === \"number\") return code === 0 || code === 200;\n\tif (typeof code === \"string\") return code === \"0\" || code === \"200\";\n\treturn false;\n}\n\nfunction unwrapEnvelope(body: unknown, operation: string): unknown {\n\tif (body && typeof body === \"object\" && (\"code\" in body || \"success\" in body)) {\n\t\tconst envelope = body as { code?: unknown; msg?: string; data?: unknown; success?: unknown };\n\t\tif (envelope.success === false || !isSuccessCode(envelope.code)) {\n\t\t\tthrow new AIError.OAuthError(`Z.ai ${operation} failed: ${envelope.msg ?? `code ${String(envelope.code)}`}`, {\n\t\t\t\tkind: \"token-exchange\",\n\t\t\t\tprovider: \"zai\",\n\t\t\t});\n\t\t}\n\t\treturn \"data\" in envelope ? envelope.data : envelope;\n\t}\n\treturn body;\n}\n\nasync function getJson(url: string, headers: Record<string, string>, fetchImpl: FetchImpl): Promise<unknown> {\n\tconst response = await fetchImpl(url, {\n\t\tmethod: \"GET\",\n\t\theaders,\n\t\tsignal: AbortSignal.timeout(30_000),\n\t});\n\tconst responseBody = await response.text();\n\tif (!response.ok) {\n\t\tthrow new AIError.ProviderHttpError(","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/registry/oauth/zai.ts#L41-L77","documentation":"Z.ai API responses arrive wrapped in an envelope ({code, msg, data} or {success,...}). unwrapEnvelope treats success===false or a non-success code as an application-level failure and throws OAuthError tagged kind=token-exchange, provider=zai, embedding the server's msg (or raw code). This is the server saying the operation itself failed, distinct from transport errors.","triggerScenarios":"Any Z.ai business-API call whose body carries success:false or a failure code: business login with an invalid/expired oauth token, org/project listing denied for the account, api key create/copy rejected (quota, permissions, name conflict).","commonSituations":"OAuth access token expired between login and exchange; account lacks organization/project provisioning; Z.ai-side rate limits or permission errors; API version changes altering the code semantics.","solutions":["Read envelope.msg in the thrown error for the server's reason and fix accordingly (usually re-auth to get a fresh oauth token).","Re-run the Z.ai OAuth login flow to obtain a new access token, then retry minting the key.","Verify the Z.ai account actually has an organization and default project before exchange.","Catch AIError.OAuthError and inspect the message/kind to distinguish auth problems from provisioning problems."],"exampleFix":"// before\nconst data = await postJson(BUSINESS_LOGIN_URL, { token: staleAccessToken }, {}, fetch);\n// after\ntry { const data = await postJson(BUSINESS_LOGIN_URL, { token: freshAccessToken }, {}, fetch); }\ncatch (e) { if (e instanceof AIError.OAuthError) await reloginZai(); throw e; }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isZaiFailureEnvelope(b: unknown): boolean { return !!b && typeof b === \"object\" && ((\"code\" in b && Number((b as any).code) !== 200) || (b as any).success === false); }","tryCatchPattern":"try { const biz = await exchangeZaiToken(oauthToken); }\ncatch (e) {\n  if (e instanceof AIError.OAuthError && e.message.includes(\"Z.ai\")) {\n    logger.warn(\"Z.ai exchange rejected\", { msg: e.message });\n    return reloginZai();\n  }\n  throw e;\n}","preventionTips":["Refresh the OAuth token before starting token-exchange flows","Pre-check account provisioning (org/project exists) before exchange","Surface envelope.msg from the error to the user instead of a generic message"],"tags":["zai","oauth","api-envelope","token-exchange","server-error"],"backgroundTag":"api-error-envelope","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}