9 months ago
Months ago i didnt have issues with the variables in my service being used during the build step in railway, now i do!
Im deploying a simple nuxt app and im using zod to verify the env variables. This works perfectly fine in my development environment with my .env file. I added the same variables to my railway service under its variables section. They are there and visible, but the nuxt build process cant seem to see them so my build fails 100% of the time.
My app just runs through the railway auto detected build process..
import { config } from 'dotenv';
import { expand } from 'dotenv-expand';
import { ZodError, z } from 'zod';
const stringBoolean = z.coerce
.string()
.transform((val) => {
return val === 'true';
})
.default('false');
const EnvSchema = z.object({
NODE_ENV: z.string().default('development'),
DATABASE_URL: z.string(),
DATABASE_SERVICE_ROLE: z.string(),
DATABASE_ANON_KEY: z.string(),
DB_MIGRATING: stringBoolean,
DB_SEEDING: stringBoolean
});
export type EnvSchema = z.infer<typeof EnvSchema>;
expand(config());
console.log('------', process.env); // <------------- I cant even see them here...
try {
EnvSchema.parse(process.env);
} catch (error) {
if (error instanceof ZodError) {
let message = 'Missing required values in .env:\n';
error.issues.forEach((issue) => {
message += issue.path[0] + '\n';
});
const e = new Error(message);
e.stack = '';
throw e;
} else {
console.error(error);
}
}
export default EnvSchema.parse(process.env);Pinned Solution
9 months ago
If you call dotenv.config() in your nuxt.config.ts, it might override Railway’s env injection, because Railway already injects them via its container runtime.
5 Replies
9 months ago
Railway does not expose service environment variables to the build process by default. It used to feel like it did (or maybe your Nuxt app previously deferred validation until runtime), but this behavior is no longer guaranteed.. especially if your app does strict checks during build.
Move .env validation to runtime
This is often the cleanest way. Don’t run Zod.parse() during the build if you can help it.
Instead:
// environment.ts
import { config } from 'dotenv';
import { expand } from 'dotenv-expand';
import { z, ZodError } from 'zod';
const stringBoolean = z.coerce.string().transform((val) => val === 'true').default('false');
const EnvSchema = z.object({
NODE_ENV: z.string().default('development'),
DATABASE_URL: z.string(),
DATABASE_SERVICE_ROLE: z.string(),
DATABASE_ANON_KEY: z.string(),
DB_MIGRATING: stringBoolean,
DB_SEEDING: stringBoolean,
});
export type EnvSchema = z.infer<typeof EnvSchema>;
expand(config());
let parsed: EnvSchema;
try {
parsed = EnvSchema.parse(process.env);
} catch (err) {
if (err instanceof ZodError && process.env.NODE_ENV !== 'production') {
console.warn('Skipping env validation in build step.');
parsed = {} as EnvSchema; // or set defaults
} else {
throw err;
}
}
export default parsed;
Then in your nuxt.config.ts, only call this file at runtime, not at config evaluation time.
teereckzi
Railway does not expose service environment variables to the build process by default. It used to feel like it did (or maybe your Nuxt app previously deferred validation until runtime), but this behavior is no longer guaranteed.. especially if your app does strict checks during build.Move .env validation to runtimeThis is often the cleanest way. Don’t run Zod.parse() during the build if you can help it.Instead:// environment.tsimport { config } from 'dotenv';import { expand } from 'dotenv-expand';import { z, ZodError } from 'zod';const stringBoolean = z.coerce.string().transform((val) => val === 'true').default('false');const EnvSchema = z.object({NODE_ENV: z.string().default('development'),DATABASE_URL: z.string(),DATABASE_SERVICE_ROLE: z.string(),DATABASE_ANON_KEY: z.string(),DB_MIGRATING: stringBoolean,DB_SEEDING: stringBoolean,});export type EnvSchema = z.infer<typeof EnvSchema>;expand(config());let parsed: EnvSchema;try {parsed = EnvSchema.parse(process.env);} catch (err) {if (err instanceof ZodError && process.env.NODE_ENV !== 'production') {console.warn('Skipping env validation in build step.');parsed = {} as EnvSchema; // or set defaults} else {throw err;}}export default parsed;Then in your nuxt.config.ts, only call this file at runtime, not at config evaluation time.
9 months ago
Railway does not expose service environment variables to the build process by default.
Yes, we do.
brody
Railway does not expose service environment variables to the build process by default.Yes, we do.
9 months ago
Yes.. Railway does expose environment variables to the build process, as long as they are set properly in the Variables panel. So from Railway’s POV, if my service has those env vars in the dashboard, they should be available at build time.
brody
Railway does not expose service environment variables to the build process by default.Yes, we do.
9 months ago
If you call dotenv.config() in your nuxt.config.ts, it might override Railway’s env injection, because Railway already injects them via its container runtime.
9 months ago
Ok, removing the config portion from my nuxt.config file solved the issue! Thanks!
Status changed to Open chandrika • 9 months ago
Status changed to Solved chandrika • 9 months ago

