mastra-ai/mastra · critical
DATABASE_URL is required outside local development and tests
Error message
DATABASE_URL is required outside local development and tests.
What it means
The mastracode web entry requires a Postgres connection string for storage in any environment that is not local development (NODE_ENV=development) or tests (NODE_ENV=test). Without DATABASE_URL (or the deprecated APP_DATABASE_URL fallback), the module cannot construct PgFactoryStorage and deliberately fails at startup instead of running with no persistent storage. Local dev falls back to a file-based LibSQL database.
Source
Thrown at mastracode/web/src/mastra/index.ts:245
// Postgres (the paired PgVector rides the same database for recall search).
// Unset (bare local dev) → libSQL on the same local file the SDK's default
// storage resolution uses, running the FULL app surface (auth, intake,
// audit, work-items, integrations) — no features silently off.
//
// `APP_DATABASE_URL` is the deprecated legacy name — still honored as a
// fallback so existing checkouts keep working, but new setups should use
// `DATABASE_URL` (matches the platform's managed env-var sync for attached
// databases, so `mastra deploy` populates it automatically).
const databaseUrl = process.env.DATABASE_URL?.trim() || process.env.APP_DATABASE_URL?.trim() || undefined;
if (process.env.APP_DATABASE_URL?.trim() && !process.env.DATABASE_URL?.trim()) {
console.warn(
'[mastracode-web] APP_DATABASE_URL is deprecated — rename it to DATABASE_URL. ' +
'The old name is honored as a fallback for now, but new deploys should use DATABASE_URL.',
);
}
const localDevelopmentMode = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test';
if (!databaseUrl && !localDevelopmentMode) {
throw new Error('DATABASE_URL is required outside local development and tests.');
}
const storage = databaseUrl
? new PgFactoryStorage({
id: 'mastra-code-storage',
connectionString: databaseUrl,
retention: DEFAULT_RETENTION,
})
: new LibSQLFactoryStorage({
id: 'mastra-code-storage',
url: `file:${getDatabasePath()}`,
retention: DEFAULT_RETENTION,
});
const vector = databaseUrl ? new PgVector({ id: 'mastra-code-vectors', connectionString: databaseUrl }) : undefined;
// Deployment-stable secret for OAuth/link `state` signing. Shared by the
// factory's integration signer and the channel-account-link deep link so both
// sign/verify with the same key: webhook secret first, then the WorkOS cookieView on GitHub (pinned to 75dd419e61)
Solutions
- Set DATABASE_URL to the Postgres connection string in the deployment environment, e.g. DATABASE_URL=postgres://user:pass@host:5432/db.
- If APP_DATABASE_URL is still set, rename it to DATABASE_URL — the old name is a deprecated fallback that will be removed.
- For local-only runs, keep NODE_ENV as development or test so the file-based LibSQL fallback is used, or still set DATABASE_URL to a local Postgres.
- Check the deploy platform's secret/variable configuration (dashboard, helm values, docker env) to confirm the variable is actually injected into the server process.
Example fix
// before (deploy env) NODE_ENV=production APP_DATABASE_URL= (unset) // after NODE_ENV=production DATABASE_URL=postgres://user:pass@db-host:5432/mastra
Defensive patterns
Strategy: validation
Validate before calling
if (!process.env.DATABASE_URL && !['development','test'].includes(process.env.NODE_ENV ?? '')) {
throw new Error('DATABASE_URL must be set for non-development environments');
} Type guard
function hasDatabaseUrl(env: NodeJS.ProcessEnv): env is NodeJS.ProcessEnv & { DATABASE_URL: string } {
return typeof env.DATABASE_URL === 'string' && env.DATABASE_URL.length > 0;
} Try / catch
try {
await startServer();
} catch (err) {
if (err instanceof Error && err.message.includes('DATABASE_URL is required')) {
console.error('Missing DATABASE_URL: set postgres://... connection string for this environment.');
process.exit(1);
}
throw err;
} Prevention
- Add DATABASE_URL to your deploy platform's required-secrets checklist (helm, terraform, docker-compose).
- Rename APP_DATABASE_URL to DATABASE_URL everywhere before the fallback is removed.
- Run a startup preflight that asserts required env vars per environment (production/staging require DATABASE_URL).
- Use NODE_ENV=development locally only when the file-based LibSQL fallback is intended.
When it happens
Trigger: Starting the server (via `mastra dev`, `mastra build`/`mastra deploy` bundling this entry) with NODE_ENV set to something other than development or test, and with neither DATABASE_URL nor APP_DATABASE_URL defined in the environment.
Common situations: Deploying to staging/production and forgetting the DATABASE_URL secret; setting NODE_ENV=production while relying on local defaults; CI jobs running the built server outside test mode; a secrets manager that names the variable differently (e.g. POSTGRES_URL); the rename from APP_DATABASE_URL to DATABASE_URL leaving the old value unset.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- FACTORY_CREDENTIAL_ENCRYPTION_PREVIOUS_KEYS values must be b
- MastraAuthBetterAuth needs a database to build its own bette
- Google client ID is required. Provide it in the options or s
- Path must include :agentId to route to the correct agent or
- @mastra/livekit: set LIVEKIT_API_KEY and LIVEKIT_API_SECRET
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4604a19e9cd01c52.
Report an issue: GitHub.