Cloudflare Workers error
ReferenceError: process is not defined
"ReferenceError: process is not defined" means your Worker read process.env, and the Workers runtime has no global process object unless Node.js compatibility is on. Variables and secrets always arrive on the env object passed to the fetch handler (env.SUPABASE_URL), on context.env in a Pages Function, or through import { env } from "cloudflare:workers". To keep process.env, add the nodejs_compat flag with a compatibility_date of 2025-04-01 or later; from 2026-08-04 the flag is on by default. With nodejs_compat and an earlier date, process.env exists but is not filled in, so every key reads as undefined. Reproduced with wrangler 4.156.0 on 2026-10-31.
Why does process.env work in Node but not in my Worker?
The Cloudflare docs say that in Workers there is no process-level environment, so by default process.env is an empty object, and that it is filled with your variables and secrets only when Node.js compatibility is on and the nodejs_compat_populate_process_env flag is active. That flag is on by default for compatibility dates of 2025-04-01 and later. Code written for Node, or generated by an AI tool that assumed Node, reads process.env everywhere, and a Worker built from a bare Wrangler config does not provide it.
We ran one Worker that reads process.env.SUPABASE_URL and env.SUPABASE_URL, with the value in a .dev.vars file. Only the process.env read changed between configs:
compatibility_date 2025-01-01, no flag ReferenceError: process is not defined
compatibility_date 2025-04-01, no flag ReferenceError: process is not defined
compatibility_date 2025-01-01, nodejs_compat process exists, process.env.SUPABASE_URL is undefined
compatibility_date 2025-04-01, nodejs_compat process.env.SUPABASE_URL has the value
compatibility_date 2026-08-04, no flag process.env.SUPABASE_URL has the value
env.SUPABASE_URL had the value in every run.Where do secrets and environment variables go for a Worker or a Pages project?
For a Worker, the docs say environment variables are on the env parameter of the fetch handler. For secrets, run wrangler secret put: it creates a new version of the Worker and deploys it immediately, and the value cannot be read back in Wrangler or the dashboard. Do not put sensitive values in vars in the Wrangler config. Use a .dev.vars file or a .env file for local development, one of them and not both.
For a Pages Function, the Pages docs read both through context.env. You set them in the dashboard under Settings, Variables and Secrets, or with vars in the Wrangler config, and Production and Preview can hold different values. Wrangler's vars are not inherited by named environments, so each environment needs its own.
npx wrangler secret put SUPABASE_ANON_KEY
// Worker
export default {
async fetch(request, env) {
const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY)
},
}
// Pages Function
export const onRequest = async (context) => {
const supabase = createClient(context.env.SUPABASE_URL, context.env.SUPABASE_ANON_KEY)
}How do I keep process.env because a library reads it?
Turn on Node.js compatibility and use a compatibility date of 2025-04-01 or later, so process.env is filled from your bindings. The docs add two caveats: values you assign to process.env are converted to strings, and with Wrangler or the Cloudflare Vite plugin process.env.NODE_ENV is replaced at build time, so it is not a runtime value. They also advise against replacing the whole process.env object with the env object.
{
"name": "notes-worker",
"main": "src/index.ts",
"compatibility_date": "2025-04-01",
"compatibility_flags": ["nodejs_compat"]
}Checklist
How to fix it, then check the fix
- 01Find every read of process.env in code that runs in the Worker:
grep -rn "process\.env" --exclude-dir=node_modules --exclude-dir=dist src functions - 02Read the value from the handler instead: env.NAME in a Worker, context.env.NAME in a Pages Function. To read it outside the handler, import { env } from "cloudflare:workers".
- 03Store each secret on the Worker. For local runs, put the same names in .dev.vars or .env and keep that file out of git:
npx wrangler secret put SUPABASE_ANON_KEY - 04If a library needs process.env, add "nodejs_compat" to compatibility_flags and set compatibility_date to 2025-04-01 or later, as in the example above.
- 05Deploy again and request the route that threw. The ReferenceError is gone, and a missing key now shows as undefined on env, which means the secret was never set on that Worker or Pages environment.
Related
Related guides
Sources
Official docs behind this checklist
- Cloudflare Workers, Environment variables
- Cloudflare Workers, Secrets
- Cloudflare Workers, Node.js process
- Cloudflare Workers, Compatibility flags
- Cloudflare Workers, Node.js compatibility
- Cloudflare Pages Functions, Bindings
- Cloudflare Workers, Wrangler configuration
- Cloudflare Workers, Supabase integration
Browse all launch guides · Read resources · How to make and check your next change
FAQ
FAQ for builders before launch
Why is process.env.NODE_ENV not what I set at runtime?
The Cloudflare docs say that with Wrangler or the Cloudflare Vite plugin, process.env.NODE_ENV is replaced at build time, so it is not a runtime value.
Did wrangler deploy remove the variables I set in the dashboard?
The Wrangler configuration docs list a keep_vars setting, described as whether Wrangler should keep variables configured in the dashboard on deploy,. Keep variables in the Wrangler config, and keep secrets on the Worker with wrangler secret put.
Should I put the key in vars so it works?
Not for a secret. The Cloudflare docs say not to store sensitive information in vars in the Wrangler configuration file; use a secret, which you cannot read back after you set it.