{"record":{"id":"f4abf176ef0496c6","repo":"mastra-ai/mastra","slug":"http-error","errorCode":"HTTP_ERROR","errorMessage":"HTTP_ERROR: Request failed with status ${response.status}","messagePattern":"HTTP_ERROR: Request failed with status (.+?)","errorType":"error_code","errorClass":"ApiCliError","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/api/client.ts","lineNumber":37,"sourceCode":"  try {\n    const { queryInput, bodyInput } = splitInput(options.descriptor, options.input);\n    const url = buildUrl(options.baseUrl, options.descriptor.path, options.pathParams, queryInput, options.apiPrefix);\n    const init: RequestInit = {\n      method: options.descriptor.method,\n      headers: { ...options.headers },\n      signal: controller.signal,\n    };\n\n    if (options.descriptor.method !== 'GET' && bodyInput) {\n      init.headers = { 'content-type': 'application/json', ...init.headers };\n      init.body = JSON.stringify(bodyInput);\n    }\n\n    const response = await fetch(url, init);\n    const body = await parseResponse(response);\n\n    if (!response.ok) {\n      throw new ApiCliError('HTTP_ERROR', `Request failed with status ${response.status}`, {\n        status: response.status,\n        body,\n      });\n    }\n\n    return body;\n  } catch (error) {\n    if (error instanceof Error && error.name === 'AbortError') {\n      throw new ApiCliError('REQUEST_TIMEOUT', `Request timed out after ${options.timeoutMs}ms`, {\n        timeoutMs: options.timeoutMs,\n      });\n    }\n    throw toApiCliError(error);\n  } finally {\n    clearTimeout(timeout);\n  }\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/cli/src/commands/api/client.ts#L19-L55","documentation":"requestApi in the CLI's API client performs an HTTP request and throws ApiCliError with code 'HTTP_ERROR' whenever the response status is not ok (response.ok is false, i.e. 4xx/5xx). The message embeds the numeric status and the error carries `status` and the parsed response `body` as details. This is the CLI's generic wrapper for any non-2xx response from the Mastra API.","triggerScenarios":"Any fetch from `requestApi` (used by fetchSchemaManifest and executeDescriptor) where the server responds 4xx/5xx: 401/403 (bad or missing auth token), 404 (wrong base URL or unknown route/version), 422 (bad request payload), 5xx (server outage).","commonSituations":"Stale or missing MASTRA_API_KEY / login session, pointing the CLI at the wrong environment URL, API version drift (CLI older than server routes), corporate proxy intercepting requests, or the server returning 500 during an incident.","solutions":["Read `error.details.status` and `error.details.body` — they tell you exactly what failed; re-authenticate if 401/403","Verify the configured base URL / environment (e.g. `mastra login` or env config) matches your deployment","Update the CLI to the latest version to avoid route/schema mismatches (404s from version drift)","For 5xx, retry with backoff and check the Mastra status/incident channels","Inspect the body field for validation details if the status is 400/422 and fix the request payload"],"exampleFix":"// before\nconst res = await client.requestApi('/registry/manifest'); // 401 HTTP_ERROR\n// after\nawait cli.login(); // refresh credentials first\nconst res = await client.requestApi('/registry/manifest');\n// or defensively\ntry {\n  const res = await client.requestApi(url);\n} catch (e) {\n  if (e.code === 'HTTP_ERROR' && e.details.status === 401) await reauthenticate();\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Before calling, ensure credentials and base URL are present\nif (!process.env.MASTRA_API_KEY) throw new Error('MASTRA_API_KEY is not set');\nnew URL(path, baseUrl); // throws early on malformed base URL","typeGuard":"import { ApiCliError } from './errors';\nfunction isHttpCliError(e: unknown): e is ApiCliError & { details: { status: number; body: unknown } } {\n  return e instanceof ApiCliError && e.code === 'HTTP_ERROR' && typeof (e.details as any)?.status === 'number';\n}","tryCatchPattern":"try {\n  const body = await client.requestApi(url, init);\n} catch (e) {\n  if (isHttpCliError(e)) {\n    const { status, body } = e.details;\n    if (status === 401 || status === 403) await reauthenticate();\n    else if (status >= 500) await retryWithBackoff(() => client.requestApi(url, init));\n    else console.error('Request rejected:', status, body);\n    return;\n  }\n  throw e;\n}","preventionTips":["Log error.details.body on every HTTP_ERROR — it contains the server's reason","Refresh auth tokens proactively; handle 401 with re-auth before surfacing the error","Pin/upgrade CLI and server versions together to avoid route drift (404s)","Retry only 5xx/network statuses with exponential backoff; never blindly retry 4xx"],"tags":["http","cli","api-error","network"],"backgroundTag":"http-request-failed-status","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}