From 45df7518c3d0071c0897f599f80c6cd338ec9655 Mon Sep 17 00:00:00 2001 From: Aman Ganapathy <84686202+nams1570@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:54:18 -0800 Subject: [PATCH] [Refactor] Rework Environment Variable Checks in Email-Rendering Pipeline (#1161) ### Context Via the email-monitor and sentry traces, we found out that we were running the "without fallback" path in production. This was because the right environment variables weren't populated in Vercel, but it exposed how our system let this slide. This occurred because the check we did for fallback vs non-fallback routes relied on checking whether a certain environment variable was empty. ### Summary of Changes We now use a sentinel value for the check instead of an empty value. Additionally, we remove default values from the `getEnvVariable` checks to ensure they throw if not populated. We also guard against the sentinel value being used in production ### Config Changes We need to update and make sure the vercel sandbox environment variables are populated in production. --- apps/backend/.env.development | 1 + apps/backend/src/lib/js-execution.tsx | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/apps/backend/.env.development b/apps/backend/.env.development index 8f30c1d1f..a11b38c8e 100644 --- a/apps/backend/.env.development +++ b/apps/backend/.env.development @@ -53,6 +53,7 @@ STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING=yes STACK_INTEGRATION_CLIENTS_CONFIG=[{"client_id": "neon-local", "client_secret": "neon-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}, {"client_id": "custom-local", "client_secret": "custom-local-secret", "id_token_signed_response_alg": "ES256", "redirect_uris": ["http://localhost:30000/api/v2/identity/authorize", "http://localhost:30000/api/v2/auth/authorize"]}] CRON_SECRET=mock_cron_secret STACK_FREESTYLE_API_KEY=mock_stack_freestyle_key +STACK_VERCEL_SANDBOX_TOKEN=vercel_sandbox_disabled_for_local_development STACK_OPENAI_API_KEY=mock_openai_api_key STACK_STRIPE_SECRET_KEY=sk_test_mockstripekey STACK_STRIPE_WEBHOOK_SECRET=mock_stripe_webhook_secret diff --git a/apps/backend/src/lib/js-execution.tsx b/apps/backend/src/lib/js-execution.tsx index 849d7696a..d98d7b2d2 100644 --- a/apps/backend/src/lib/js-execution.tsx +++ b/apps/backend/src/lib/js-execution.tsx @@ -57,9 +57,9 @@ function createVercelSandboxEngine(): JsEngine { return { name: 'vercel-sandbox', execute: async (code: string, options: ExecuteJavascriptOptions): Promise => { - const teamId = getEnvVariable("STACK_VERCEL_SANDBOX_TEAM_ID", ""); - const projectId = getEnvVariable("STACK_VERCEL_SANDBOX_PROJECT_ID", ""); - const token = getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN", ""); + const teamId = getEnvVariable("STACK_VERCEL_SANDBOX_TEAM_ID"); + const projectId = getEnvVariable("STACK_VERCEL_SANDBOX_PROJECT_ID"); + const token = getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN"); const sandbox = await Sandbox.create({ resources: { vcpus: 2 }, @@ -139,11 +139,7 @@ export async function executeJavascript(code: string, options: ExecuteJavascript } }, async () => { - if (getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN","") != "") { - if (!getNodeEnvironment().includes("prod")) { - throw new StackAssertionError("STACK_VERCEL_SANDBOX_TOKEN is set in non-production environment. We do not use Vercel Sandbox in non-production environments."); - } - + if (getEnvVariable("STACK_VERCEL_SANDBOX_TOKEN") != "vercel_sandbox_disabled_for_local_development") { const shouldSanityTest = Math.random() < 0.05; if (shouldSanityTest) { runAsynchronouslyAndWaitUntil(runSanityTest(code, options)); @@ -151,6 +147,10 @@ export async function executeJavascript(code: string, options: ExecuteJavascript return await runWithFallback(code, options); } else { + if (getNodeEnvironment().includes("prod")) { + throw new StackAssertionError("STACK_VERCEL_SANDBOX_TOKEN is set to the disabled sentinel value in production. Please configure a real Vercel Sandbox token."); + } + return await runWithoutFallback(code, options); } });