{"record":{"id":"f2a94a90280684cd","repo":"mastra-ai/mastra","slug":"detail","errorCode":null,"errorMessage":"detail","messagePattern":"detail","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/auth/client.ts","lineNumber":43,"sourceCode":"  if (MASTRA_PLATFORM_API_URL.includes('staging')) return 'https://studio.staging.mastra.ai';\n  return 'https://studio.mastra.ai';\n}\n\nexport const MASTRA_STUDIO_URL = deriveStudioUrl();\n\nexport const SESSION_EXPIRED_MESSAGE = 'Session expired. Run: mastra auth login';\n\n/**\n * Throw a standardized error for API failures.\n * - 401: \"Session expired\" (authentication failed)\n * - Other: Show the server's error detail or fall back to status code\n */\nexport function throwApiError(message: string, status: number, detail?: string): never {\n  if (status === 401) {\n    throw new Error(SESSION_EXPIRED_MESSAGE);\n  }\n  if (detail) {\n    throw new Error(detail);\n  }\n  throw new Error(`${message}: ${status}`);\n}\n\n/** Best-effort message from platform JSON error bodies (RFC 7807 `detail`, etc.). */\nexport function extractApiErrorDetail(error: unknown): string | undefined {\n  if (!error || typeof error !== 'object') return undefined;\n  const o = error as Record<string, unknown>;\n\n  let detail: string | undefined;\n  if (typeof o.detail === 'string' && o.detail.trim()) detail = o.detail;\n  else if (typeof o.message === 'string' && o.message.trim()) detail = o.message;\n  else if (typeof o.error === 'string' && o.error.trim()) detail = o.error;\n\n  // Validation errors (400) carry the useful part in errors[] — field name plus\n  // message (e.g. the valid-options enum for a bad --region). Without this the\n  // user only sees \"The request body contains invalid fields\".\n  const fieldErrors = Array.isArray(o.errors)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/auth/client.ts#L25-L61","documentation":"When the platform API returns a non-401 error and the response body includes an error detail (e.g. an RFC 7807 `detail` field), throwApiError rethrows that server-provided detail string verbatim as the Error message. The developer sees the server's own explanation of why the request failed.","triggerScenarios":"fetchOrgs, createToken, listTokensAction, revokeTokenAction, or fetchProjects receives a non-401 HTTP error (400/403/404/409/500) whose JSON body carries a detail/description field; that raw detail string becomes the thrown message.","commonSituations":"Revoking a token that does not exist (404), creating a token with an invalid name (400), lacking org permissions (403), platform 5xx with a structured error body.","solutions":["Read the detail message — it comes directly from the Mastra platform and names the failing constraint.","Fix the request inputs the detail points to (token id, org id, payload fields).","Retry after fixing; if detail is a 5xx artifact, retry later or check platform status."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isServerDetailError(err: unknown): err is Error {\n  return err instanceof Error && !err.message.startsWith('Session expired');\n}","tryCatchPattern":"try {\n  await createToken(token, name);\n} catch (err) {\n  if (err instanceof Error) {\n    // message is the server-provided detail; surface it to the user verbatim\n    console.error(`Request rejected by platform: ${err.message}`);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Validate request payloads (token names, ids) against platform constraints before sending.","Log full request context when retrying so server details map back to the failing call.","Treat server detail strings as authoritative — do not string-match on them for control flow, use HTTP status where available."],"tags":["cli","api","server-error","http"],"backgroundTag":"api-error-response","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}