How to Fix AI Breaking the Cloudflare Workers Runtime
AI agents import Node.js built-ins like fs, crypto, and path into Cloudflare Workers, causing runtime errors because the Workers runtime is not Node.js.
CursorClaude CodeCodexWindsurf CloudflareTypeScript
The agent writes code that works locally under Node.js but fails at deploy or runtime in Cloudflare Workers because the Workers runtime is a V8 isolate — not Node.js.
The symptom
The agent imports Node.js built-ins or npm packages that internally require Node.js APIs.
// worker.ts — WRONGimport { createHash } from "crypto"; // Node built-in — not availableimport { readFileSync } from "fs"; // Node built-in — not availableimport { resolve } from "path"; // Node built-in — not availableimport { IncomingMessage } from "http"; // Node built-in — not available
export default { async fetch(request: Request, env: Env) { const hash = createHash("sha256").update("data").digest("hex"); return new Response(hash); },};// Error at runtime: Cannot read properties of undefined (reading 'createHash')Why it happens
Most agent training data targets Node.js. The model knows crypto, fs, and
path work for hashing, file access, and path manipulation, so it reaches for
them. It doesn’t distinguish the Workers runtime from Node.js unless explicitly
told.
How to spot it
import ... from "crypto"/"fs"/"path"/"http"/"stream"in Worker files.wrangler devworks butwrangler deploythrows a bundling warning about unresolved Node.js modules.- The Wrangler compatibility flags section in
wrangler.tomlis missing or uses a date before2022-11-30. - Dependencies that internally use
require("node:...")without a Workers compatibility shim.
How to fix it
Use Web Standard APIs — they are available natively in Workers.
// worker.ts — CORRECTexport default { async fetch(request: Request, env: Env) { // Web Crypto API — standard, available in Workers const encoder = new TextEncoder(); const data = encoder.encode("data"); const hashBuffer = await crypto.subtle.digest("SHA-256", data); const hashArray = Array.from(new Uint8Array(hashBuffer)); const hash = hashArray.map((b) => b.toString(16).padStart(2, "0")).join(""); return new Response(hash); },};# wrangler.toml — enable Node.js compat shims for packages that need themcompatibility_date = "2024-09-23"compatibility_flags = ["nodejs_compat"][ ] No imports from "crypto", "fs", "path", "http", "stream", "os", "buffer" (use node: prefix + nodejs_compat flag if unavoidable)[ ] Use crypto.subtle for hashing/signing (Web Crypto API)[ ] Use env bindings (KV, R2, D1) instead of fs for storage[ ] Set compatibility_date to a recent date in wrangler.toml[ ] Add nodejs_compat flag only for third-party packages that require it[ ] Run "wrangler deploy --dry-run" to catch bundling errors before deployingFix Prompt
This code imports Node.js built-in modules (crypto, fs, path, http) that arenot available in the Cloudflare Workers runtime. Rewrite it using Web StandardAPIs: crypto.subtle for hashing/encryption, the Fetch API for HTTP, andCloudflare bindings (KV, R2, D1) for storage. If a third-party dependencyrequires Node.js APIs, add nodejs_compat to compatibility_flags in wrangler.tomland note that in a comment.Test
# Dry-run deploy to catch Node.js module errorswrangler deploy --dry-run --outdir dist 2>&1 | grep -i "error\|unresolved\|node:" && echo "FAIL" || echo "OK"
# Check for raw Node built-in importsgrep -rn '^import.*from "(crypto|fs|path|http|stream|os)"' src/ \ && echo "FAIL: Node.js built-in import found" || echo "OK"