withastro/astro · error · AstroError
EnvInvalidVariables
EnvInvalidVariables
Error message
The following environment variables defined in `env.schema` are invalid:
${errors} What it means
At dev/build time Astro validates every variable declared in `env.schema` against the actual environment. When one or more fail (missing value, or a value that does not satisfy the declared type) and this is not a type-generation-only sync run, it throws EnvInvalidVariables listing each invalid key, its declared type, and the specific validation errors.
Solutions
- Set every listed variable where Astro reads it: .env (and .env.production) for local, deployment secrets/environment variables for CI and production.
- If absence is a supported state, declare the variable optional (envField.string({ access: 'secret', optional: true })) and handle undefined in code.
- Fix declared types to match reality - correct enum values, number where the value is numeric.
- Add an env preflight step to CI that fails before the build when required variables are missing.
Example fix
// before - required secret that is never set anywhere
export default defineConfig({
env: { schema: { STRIPE_KEY: envField.string({ access: 'secret' }) } },
});
// after - optional with an explicit server-side check
export default defineConfig({
env: { schema: { STRIPE_KEY: envField.string({ access: 'secret', optional: true }) } },
}); Defensive patterns
Strategy: validation
Validate before calling
// preflight before `astro build` in CI
const required = ['SECRET_API_KEY', 'PUBLIC_SITE_URL'];
const missing = required.filter((k) => !process.env[k]);
if (missing.length) {
console.error('missing env vars:', missing.join(', '));
process.exit(1);
} Prevention
- Keep .env.example in sync with env.schema and make onboarding copy it.
- Declare variables optional only when absence is a supported state; otherwise keep them required so failures are loud.
- Add an env preflight step to CI so missing variables fail before the Astro build, with a clear message.
When it happens
Trigger: Declaring `STRIPE_KEY: envField.string({ access: 'secret' })` but never providing STRIPE_KEY; declaring a number or enum while the environment holds a non-matching string ('abc' for number, a value outside the enum); a required public variable missing at build time in CI; optional/required mismatches between schema and reality.
Common situations: A teammate cloning the repo without the project's .env file; CI or deployment platform missing configured secrets; renaming a variable in env.schema but not in the deployment environment; values quoted or formatted so the declared type rejects them.
Related errors
- EnvPrefixConflictsWithSecret
- Unable to read wrangler config, variables defined in it…
- Apps must be an object with an id, a name and an entrypoint.
- [astro] deprecated. Move onto your processor instead (e.g…
- `Astro.session` was accessed but no session storage is…
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/e74e9a24e0baa4e0.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/env/vite-plugin-env.ts:160
for (const [key, options] of Object.entries(schema)) {
const variable = loadedEnv[key] === '' ? undefined : loadedEnv[key];
if (options.access === 'secret' && !validateSecrets) {
continue;
}
const result = validateEnvVariable(variable, options);
const type = getEnvFieldType(options);
if (!result.ok) {
invalid.push({ key, type, errors: result.errors });
// We don't do anything with validated secrets so we don't store them
} else if (options.access === 'public') {
valid.push({ key, value: result.value, type, context: options.context });
}
}
if (invalid.length > 0 && !sync) {
throw new AstroError({
...AstroErrorData.EnvInvalidVariables,
message: AstroErrorData.EnvInvalidVariables.message(invalidVariablesToError(invalid)),
});
}
return valid;
}
let cachedServerTemplate: string | undefined;
function getTemplates({
schema,
validatedVariables,
loadedEnv,
}: {
schema: EnvSchema;
validatedVariables: Array<ValidVariable>;
loadedEnv: Record<string, string> | null;View on GitHub (pinned to 52e6c34790)