mastra-ai/mastra · error · PlatformApiError
Failed to read database status — ${await extractError(res)}
Error message
Failed to read database status — ${await extractError(res)} What it means
getDatabaseStatus polls GET /v1/server/projects/:projectId/databases/:databaseId to check Neon provisioning progress. A non-ok response aborts the polling loop immediately with this PlatformApiError containing the upstream status and server error text.
Source
Thrown at mastracode/mastra-factory/src/platform.ts:175
export async function getDatabaseStatus({
token,
orgId,
projectId,
databaseId,
signal,
}: {
token: string;
orgId: string;
projectId: string;
databaseId: string;
signal?: AbortSignal;
}): Promise<AttachedDatabase> {
const res = await platformFetch(
`${MASTRA_PLATFORM_API_URL}/v1/server/projects/${encodeURIComponent(projectId)}/databases/${encodeURIComponent(databaseId)}`,
{ headers: authHeaders(token, orgId), signal },
);
if (!res.ok) {
throw new PlatformApiError(res.status, `Failed to read database status — ${await extractError(res)}`);
}
const body = (await res.json()) as { database: AttachedDatabase };
return body.database;
}
/** GET /v1/server/projects/:id/databases/:dbId/connection — only 200s when `ready`. */
export async function getDatabaseConnection({
token,
orgId,
projectId,
databaseId,
}: {
token: string;
orgId: string;
projectId: string;
databaseId: string;
}): Promise<DatabaseConnection> {
const res = await platformFetch(View on GitHub (pinned to 75dd419e61)
Solutions
- Check the status after the em-dash: re-login on 401, verify ids on 404, back off on 429.
- Confirm the database still exists in the platform dashboard and rerun if it was deleted.
- Reduce polling frequency (increase intervalMs in waitForDatabaseReady) if rate-limited.
- Retry the whole provisioning flow after transient 5xx errors.
Example fix
// before
const db = await waitForDatabaseReady({ token, orgId, projectId, databaseId });
// after
const db = await waitForDatabaseReady({ token, orgId, projectId, databaseId, intervalMs: 3000 }); // slower poll avoids 429 Defensive patterns
Strategy: retry
Validate before calling
// verify ids are non-empty before polling
if (!projectId || !databaseId) throw new Error('projectId and databaseId are required for status polling'); Try / catch
try {
const db = await waitForDatabaseReady({ token, orgId, projectId, databaseId });
} catch (err) {
if (err instanceof PlatformApiError && (err.status === 401 || err.status === 429)) {
await refreshAuth(); await sleep(3000);
return waitForDatabaseReady({ token, orgId, projectId, databaseId, intervalMs: 5000 });
}
throw err;
} Prevention
- Use a polling interval of a few seconds to avoid 429s.
- Refresh the auth token if provisioning is expected to take many minutes.
- Confirm the database/project still exist before and during polling.
- Treat 4xx as terminal; retry only 429/5xx.
When it happens
Trigger: The status poll returns 401 (token expired during the wait), 403, 404 (database or project id wrong/deleted), 429 (polling too fast), or 5xx — from inside waitForDatabaseReady's loop.
Common situations: Long-running provisioning where the token expires mid-poll; database deleted by a teammate while waiting; wrong project/database ids after a re-run; aggressive polling tripping rate limits.
Related errors
- Failed to create project — ${await extractError(res)}
- Failed to attach Neon database — ${await extractError(res)}
- Failed to fetch CDP version info from ${versionUrl}: ${respo
- Request failed (${res.status}) / server-provided message
- Failed to load GitHub token status (${res.status})
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/604feec877f5a43e.
Report an issue: GitHub.