mastra-ai/mastra · error · PlatformApiError
Failed to create API key — ${await extractError(res)}
Error message
Failed to create API key — ${await extractError(res)} What it means
mintOrgApiKey POSTs to /v1/auth/tokens with `{ name: keyName }` and org auth headers to mint a new org-scoped API key. Any non-ok response becomes a PlatformApiError with the upstream status and server error text, prefixed with 'Failed to create API key —'.
Source
Thrown at mastracode/mastra-factory/src/platform.ts:109
* POST /v1/auth/tokens — mint an `sk_` WorkOS org API key.
* Returns the plaintext secret; the platform never returns it again.
*/
export async function mintOrgApiKey({
token,
orgId,
keyName,
}: {
token: string;
orgId: string;
keyName: string;
}): Promise<string> {
const res = await platformFetch(`${MASTRA_PLATFORM_API_URL}/v1/auth/tokens`, {
method: 'POST',
headers: { ...authHeaders(token, orgId), 'Content-Type': 'application/json' },
body: JSON.stringify({ name: keyName }),
});
if (!res.ok) {
throw new PlatformApiError(res.status, `Failed to create API key — ${await extractError(res)}`);
}
const body = (await res.json()) as CreateTokenResponse;
return body.secret;
}
/**
* POST /v1/server/projects/:id/databases — attach a Neon Postgres database.
* Returns immediately with `status: 'provisioning'`; poll for `ready`.
*
* Note: this route requires `requireRole('admin')`. Non-admin org members
* will get a 403.
*/
export async function attachNeonDatabase({
token,
orgId,
projectId,
name,
regionId,View on GitHub (pinned to 75dd419e61)
Solutions
- Check the message after the em-dash and address the stated cause (auth, name collision, permissions).
- Re-authenticate to refresh an expired token, then rerun create-factory.
- Ask an org admin to run the command or mint the key from the dashboard if your role lacks permission.
- Retry after backoff if the status is 429 or 5xx.
Example fix
// before
const secret = await mintOrgApiKey({ token, orgId, keyName: 'factory' });
// after
let secret: string;
try {
secret = await mintOrgApiKey({ token, orgId, keyName: 'factory' });
} catch (e) {
if (e instanceof PlatformApiError && e.status === 409) {
secret = await mintOrgApiKey({ token, orgId, keyName: `factory-${Date.now()}` });
} else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!keyName || keyName.length > 100) throw new Error('API key name must be 1-100 chars');
// optionally verify uniqueness if the platform lists existing tokens:
const tokens = await listOrgTokens({ token, orgId });
if (tokens.some(t => t.name === keyName)) throw new Error(`Key name '${keyName}' already exists`); Type guard
function isPlatformApiError(e) { return e instanceof PlatformApiError; } Try / catch
try {
secret = await mintOrgApiKey({ token, orgId, keyName });
} catch (err) {
if (err instanceof PlatformApiError && (err.status === 429 || err.status >= 500)) {
await sleep(2000); secret = await mintOrgApiKey({ token, orgId, keyName });
} else throw err;
} Prevention
- Use unique key names (append timestamp/suffix) to avoid collisions.
- Confirm admin role before attempting org-level key minting.
- Refresh expired tokens before multi-step provisioning.
- Back off and retry on 429/5xx.
When it happens
Trigger: POST /v1/auth/tokens returns 4xx/5xx: 401/403 for expired token or insufficient org permissions, 409/422 for a duplicate or invalid key name, 429 rate limiting, 5xx platform errors.
Common situations: Non-admin user trying to mint org keys; token expired mid-provisioning; key name colliding with an existing token; org hitting key-count limits; transient 502/503 from the platform.
Related errors
- invalid API key or insufficient permissions
- Failed to create project — ${await extractError(res)}
- Failed to attach Neon database — ${await extractError(res)}
- Failed to read database status — ${await extractError(res)}
- Failed to fetch connection string — ${await extractError(res
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/dfcc0a47dc7db045.
Report an issue: GitHub.