mastra-ai/mastra · error · PlatformApiError

Failed to attach Neon database — ${await extractError(res)}

Error message

Failed to attach Neon database — ${await extractError(res)}

What it means

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).

Source

Thrown at mastracode/mastra-factory/src/platform.ts:150

  name: string;
  regionId: string;
}): Promise<AttachedDatabase> {
  const res = await platformFetch(
    `${MASTRA_PLATFORM_API_URL}/v1/server/projects/${encodeURIComponent(projectId)}/databases`,
    {
      method: 'POST',
      headers: { ...authHeaders(token, orgId), 'Content-Type': 'application/json' },
      body: JSON.stringify({ kind: 'neon', name, regionId }),
    },
  );
  if (!res.ok) {
    if (res.status === 403) {
      throw new PlatformApiError(
        403,
        `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.`,
      );
    }
    throw new PlatformApiError(res.status, `Failed to attach Neon database — ${await extractError(res)}`);
  }
  const body = (await res.json()) as AttachDatabaseResponse;
  return body.database;
}

/** GET /v1/server/projects/:id/databases/:dbId — status poll target. */
export async function getDatabaseStatus({
  token,
  orgId,
  projectId,
  databaseId,
  signal,
}: {
  token: string;
  orgId: string;
  projectId: string;
  databaseId: string;
  signal?: AbortSignal;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the status + message after the em-dash and fix the stated cause.
  2. Validate the regionId against the platform's supported Neon regions.
  3. Re-authenticate if the token may have expired, and confirm the project belongs to the --org used.
  4. Retry with backoff for 429/5xx statuses.

Example fix

// before
await attachNeonDatabase({ token, orgId, projectId, name: 'db', regionId: 'eastus' });
// after
await attachNeonDatabase({ token, orgId, projectId, name: 'db', regionId: 'aws-us-east-1' });
Defensive patterns

Strategy: retry

Validate before calling

if (!/^[a-zA-Z0-9][a-zA-Z0-9-_]*$/.test(name)) throw new Error('Invalid database name');
if (!supportedNeonRegions.includes(regionId)) throw new Error(`Unsupported Neon region: ${regionId}`);

Type guard

function isPlatformApiError(e) { return e instanceof PlatformApiError; }

Try / catch

for (let attempt = 1; attempt <= 3; attempt++) {
  try { return await attachNeonDatabase(opts); }
  catch (err) {
    if (err instanceof PlatformApiError && (err.status === 429 || err.status >= 500) && attempt < 3) {
      await sleep(1000 * 2 ** attempt); continue;
    }
    if (err.status === 403) throw err; // surfaced separately as permissions issue
    throw err;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/d064ec1748536efd. Report an issue: GitHub.