From 9ad92b9e4e24f0165f5aeed3791c1d3b54e58a85 Mon Sep 17 00:00:00 2001 From: BilalG1 Date: Tue, 16 Jun 2026 12:53:51 -0700 Subject: [PATCH] Fix dashboard build crash: preserve empty/sentinel passthrough in inline env resolver resolveInlineRenamedEnvVar collapsed empty-string and unreplaced-sentinel values to `undefined` via its `|| ... || undefined` tail. The pre-rename inline (`process.env.HEXCLAVE ?? process.env.STACK`) returned the raw value, so an unset NEXT_PUBLIC_* var (which Next inlines as "") came through as "" and downstream `getPublicEnvVar(...) ?? throwErr(...)` readers were satisfied. Returning `undefined` instead made those `?? throwErr` checks fire during `next build` page-data collection (e.g. the AI companion widget's NEXT_PUBLIC_BROWSER_STACK_API_URL read), crashing the dashboard build in the check-prisma-migrations job (which builds the dashboard via the CLI's rde-standalone bundle). Restore the `??` passthrough for the raw fallback so empty/sentinel values are preserved, while keeping conflict detection and the empty-as-unset shadowing protection (a real STACK value is still returned over an empty HEXCLAVE one). Verified: dashboard `next build` collects page data without throwing. --- apps/dashboard/src/lib/env.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/src/lib/env.tsx b/apps/dashboard/src/lib/env.tsx index 81640df22..f02b23f2a 100644 --- a/apps/dashboard/src/lib/env.tsx +++ b/apps/dashboard/src/lib/env.tsx @@ -22,7 +22,13 @@ function resolveInlineRenamedEnvVar(hexclaveName: string, stackName: string, hex ) { throw new Error(`Environment variables ${hexclaveName} and ${stackName} are both set to different values. Remove one of them or set them to the same value.`); } - return usableHexclaveValue || usableStackValue || hexclaveValue || stackValue || undefined; + // Prefer a real (non-sentinel) Hexclave value, then a real Stack value. When + // neither is "real", fall back to the raw value with `??` so an empty-string + // placeholder or an unreplaced sentinel is passed through unchanged (matching + // the pre-rename `process.env.X ?? process.env.Y` inline behavior) instead of + // collapsing to `undefined` — downstream readers use `?? throwErr(...)`, which + // treats `undefined` (but not `""`) as "missing" and would crash the build. + return usableHexclaveValue || usableStackValue || (hexclaveValue ?? stackValue); } // Hexclave rebrand: each entry prefers the NEXT_PUBLIC_HEXCLAVE_* literal, falling back