@@ -38,7 +38,16 @@ const envSchema = z
3838 . object ( {
3939 DATABASE_URL : z . url ( ) ,
4040 BETTER_AUTH_SECRET : emptyToUndefined . pipe ( z . string ( ) . min ( 32 , 'BETTER_AUTH_SECRET must be at least 32 characters' ) ) ,
41- BETTER_AUTH_URL : emptyToUndefined . pipe ( z . url ( ) ) . optional ( ) ,
41+ BETTER_AUTH_URL : z . preprocess (
42+ ( val ) => {
43+ if ( typeof val !== 'string' ) return val
44+ const trimmed = val . trim ( )
45+ // Treat empty strings and broken Railway template refs ("https://") as unset
46+ if ( trimmed === '' || trimmed === 'https://' || trimmed === 'http://' ) return undefined
47+ return trimmed
48+ } ,
49+ z . string ( ) . url ( ) ,
50+ ) . optional ( ) ,
4251 /** Comma-separated list of additional trusted origins for Better Auth CSRF checks. */
4352 BETTER_AUTH_TRUSTED_ORIGINS : emptyToUndefined
4453 . pipe ( z . string ( ) )
@@ -81,17 +90,13 @@ const envSchema = z
8190 CRON_SECRET : emptyToUndefined . pipe ( z . string ( ) . min ( 16 ) ) . optional ( ) ,
8291 } )
8392 . superRefine ( ( data , ctx ) => {
84- const hasPreviewDomain = data . RAILWAY_PUBLIC_DOMAIN
85- ? data . RAILWAY_PUBLIC_DOMAIN . toLowerCase ( ) . includes ( '-pr-' )
86- : false
87- const hasPrNumber = ! ! data . RAILWAY_GIT_PR_NUMBER
88- const isPreview = isRailwayPreviewEnvironment ( data . RAILWAY_ENVIRONMENT_NAME ) || hasPreviewDomain || hasPrNumber
89-
90- if ( ! isPreview && ! data . BETTER_AUTH_URL ) {
93+ // BETTER_AUTH_URL can be derived at runtime from RAILWAY_PUBLIC_DOMAIN,
94+ // so it's only required when not running on Railway.
95+ if ( ! data . BETTER_AUTH_URL && ! data . RAILWAY_PUBLIC_DOMAIN ) {
9196 ctx . addIssue ( {
9297 code : z . ZodIssueCode . custom ,
9398 path : [ 'BETTER_AUTH_URL' ] ,
94- message : 'BETTER_AUTH_URL is required outside Railway PR/preview environments ' ,
99+ message : 'BETTER_AUTH_URL is required when RAILWAY_PUBLIC_DOMAIN is not available ' ,
95100 } )
96101 }
97102 } )
@@ -124,7 +129,7 @@ export const env = new Proxy({} as z.infer<typeof envSchema>, {
124129 `\n[Reqcore] ❌ Missing or invalid environment variables:\n${ missing } \n\n` +
125130 `Ensure these variables are set in your Railway service (Settings → Variables).\n` +
126131 `Required: DATABASE_URL, BETTER_AUTH_SECRET, S3_ENDPOINT, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET\n` +
127- `Required outside Railway PR/preview environments : BETTER_AUTH_URL\n` +
132+ `Required when not on Railway : BETTER_AUTH_URL (or generate a Railway domain) \n` +
128133 `Optional: BETTER_AUTH_TRUSTED_ORIGINS, S3_REGION (default: us-east-1), S3_FORCE_PATH_STYLE (default: true), TRUSTED_PROXY_IP, DEMO_ORG_SLUG, RESEND_API_KEY, RESEND_FROM_EMAIL\n` ,
129134 )
130135 throw result . error
0 commit comments