{"record":{"id":"d064ec1748536efd","repo":"mastra-ai/mastra","slug":"failed-to-attach-neon-database-await-extracter","errorCode":null,"errorMessage":"Failed to attach Neon database — ${await extractError(res)}","messagePattern":"Failed to attach Neon database — (.+?)","errorType":"http","errorClass":"PlatformApiError","httpStatus":null,"severity":"error","filePath":"mastracode/mastra-factory/src/platform.ts","lineNumber":150,"sourceCode":"  name: string;\n  regionId: string;\n}): Promise<AttachedDatabase> {\n  const res = await platformFetch(\n    `${MASTRA_PLATFORM_API_URL}/v1/server/projects/${encodeURIComponent(projectId)}/databases`,\n    {\n      method: 'POST',\n      headers: { ...authHeaders(token, orgId), 'Content-Type': 'application/json' },\n      body: JSON.stringify({ kind: 'neon', name, regionId }),\n    },\n  );\n  if (!res.ok) {\n    if (res.status === 403) {\n      throw new PlatformApiError(\n        403,\n        `Attaching a database requires the admin role in your organization. Ask an org admin to run \\`create-factory\\`, or attach a database from the dashboard.`,\n      );\n    }\n    throw new PlatformApiError(res.status, `Failed to attach Neon database — ${await extractError(res)}`);\n  }\n  const body = (await res.json()) as AttachDatabaseResponse;\n  return body.database;\n}\n\n/** GET /v1/server/projects/:id/databases/:dbId — status poll target. */\nexport async function getDatabaseStatus({\n  token,\n  orgId,\n  projectId,\n  databaseId,\n  signal,\n}: {\n  token: string;\n  orgId: string;\n  projectId: string;\n  databaseId: string;\n  signal?: AbortSignal;","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/mastra-factory/src/platform.ts#L132-L168","documentation":"Fallback error for attachNeonDatabase: any non-ok, non-403 response from the attach-database endpoint is converted into a PlatformApiError carrying the upstream HTTP status and the server's error text (via extractError).","triggerScenarios":"POST to the attach database endpoint returns 400 (invalid regionId or name), 401 (bad token), 404 (project not found in org), 409 (name conflict/database already attached), 429, or 5xx.","commonSituations":"Typo'd or unsupported regionId; project ID referenced from a different org than the auth headers; token expired between steps; database with the same name already attached; platform outage returning 502/503.","solutions":["Read the status + message after the em-dash and fix the stated cause.","Validate the regionId against the platform's supported Neon regions.","Re-authenticate if the token may have expired, and confirm the project belongs to the --org used.","Retry with backoff for 429/5xx statuses."],"exampleFix":"// before\nawait attachNeonDatabase({ token, orgId, projectId, name: 'db', regionId: 'eastus' });\n// after\nawait attachNeonDatabase({ token, orgId, projectId, name: 'db', regionId: 'aws-us-east-1' });","handlingStrategy":"retry","validationCode":"if (!/^[a-zA-Z0-9][a-zA-Z0-9-_]*$/.test(name)) throw new Error('Invalid database name');\nif (!supportedNeonRegions.includes(regionId)) throw new Error(`Unsupported Neon region: ${regionId}`);","typeGuard":"function isPlatformApiError(e) { return e instanceof PlatformApiError; }","tryCatchPattern":"for (let attempt = 1; attempt <= 3; attempt++) {\n  try { return await attachNeonDatabase(opts); }\n  catch (err) {\n    if (err instanceof PlatformApiError && (err.status === 429 || err.status >= 500) && attempt < 3) {\n      await sleep(1000 * 2 ** attempt); continue;\n    }\n    if (err.status === 403) throw err; // surfaced separately as permissions issue\n    throw err;\n  }\n}","preventionTips":["Validate regionId and name against platform/Neon constraints before calling.","Re-authenticate before long provisioning sequences.","Retry 429/5xx with exponential backoff; never retry 4xx auth/permission errors.","Ensure the projectId belongs to the same org as the auth headers."],"tags":["http-error","platform-api","neon","network"],"backgroundTag":"http-api-error","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}