Next.js EvalError Fix: When Code Generation Is Disallowed
Diagnose Next.js middleware EvalError by checking Node, Homebrew, and version managers to fix Edge Runtime issues.

⚡ Next.js Implementation Guides
In-depth Next.js guides covering App Router, RSC, ISR, and deployment. Get code examples, optimization checklists, and prompts to accelerate development.
Last week I was setting up Docker with Colima on my MacBook for a Next.js 15 multi-tenant project. Everything was working fine until suddenly it wasn't. My terminal exploded with this error:
EvalError: Code generation from strings disallowed for this context
at <unknown> (.next/server/middleware.js:535)
I spent an hour checking my middleware imports, convinced I had accidentally pulled in some Node.js-only package into the Edge Runtime. The code was clean. The imports were minimal. Nothing made sense.
Turns out, the problem had nothing to do with my code at all.
The Misleading Error
Here's what my console looked like when running pnpm dev:
⚠ You are using a non-standard "NODE_ENV" value in your environment.
▲ Next.js 15.5.9
⨯ EvalError: Code generation from strings disallowed for this context
at <unknown> (.next/server/middleware.js:535)
at (middleware)/./node_modules/.pnpm/next@15.5.9.../node_modules/next/dist/build/webpack/loaders/next-middleware-loader.js
If you've worked with Next.js middleware before, you know this error usually means you're importing something that uses eval(), new Function(), or other dynamic code generation that the Edge Runtime doesn't allow.
The typical culprits are Payload CMS imports, database clients like Drizzle or Prisma, or Node.js built-ins like fs and path.
The Wrong Debugging Path
My middleware was straightforward — just tenant routing based on hostname:
// File: src/middleware.ts
import { NextResponse, type NextRequest } from 'next/server';
import { getTenantByHost } from '@/lib/tenants';
export async function middleware(req: NextRequest) {
const hostname = req.headers.get('host') || '';
const tenantConfig = getTenantByHost(hostname);
// ... routing logic
}
And my getTenantByHost function was completely Edge-safe — just a pure TypeScript lookup with zero external imports:
// File: lib/tenants.ts
export const TENANTS = [
{ index: '1', slug: 'adart', host: 'adart.local' },
{ index: '2', slug: 'making-light', host: 'making-light.local' },
] as const;
export function getTenantByHost(host: string) {
return TENANTS.find(tenant => tenant.host === host);
}
No Payload imports. No database queries. No Node.js APIs. The code was clean.
The Real Clue
When I tried to run npx vercel to deploy, I got a completely different error:
dyld[77634]: Library not loaded: /opt/homebrew/opt/simdjson/lib/libsimdjson.28.dylib
Referenced from: /opt/homebrew/Cellar/node@22/22.21.1/bin/node
Reason: tried: '/opt/homebrew/opt/simdjson/lib/libsimdjson.28.dylib' (no such file)
[1] 77634 abort npx vercel
This was the actual problem. My Node.js installation was broken at the system level.
When you see dyld Library not loaded errors on macOS, it means a native library dependency is missing or version-mismatched. This can cause all sorts of bizarre downstream errors that look completely unrelated.
What Actually Happened
Setting up Colima and Docker on macOS triggered Homebrew updates. During this process, Homebrew upgraded simdjson from version 28 to 4.2.4, but my Node@22 installation was still compiled against the old libsimdjson.28.dylib that no longer existed.
Making things worse, I had three different Node managers fighting each other in my ~/.zshrc:
# Homebrew's Node 22 (broken)
export PATH="/opt/homebrew/opt/node@22/bin:$PATH"
# Homebrew's Node 24 (newly installed)
export PATH="/opt/homebrew/opt/node@24/bin:$PATH"
# NVM (working, but being overridden)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
My shell was picking up the broken Homebrew Node for some commands and nvm's Node for others. The result was a frankenstein environment where nothing worked correctly, and the errors were completely misleading.
The Fix
The solution was to pick one Node version manager and stick with it. Since I already had nvm installed with a working Node v24, I cleaned up the Homebrew entries:
# Remove the conflicting Homebrew PATH entries
sed -i '' '/export PATH="\/opt\/homebrew\/opt\/node@2[24]\/bin:\$PATH"/d' ~/.zshrc
# Reload shell config
source ~/.zshrc
# Verify nvm is now in control
which node
# Should output: /Users/yourname/.nvm/versions/node/v24.x.x/bin/node
which pnpm
# Should output: /Users/yourname/.nvm/versions/node/v24.x.x/bin/pnpm
After cleaning up the PATH conflicts and ensuring nvm was managing Node, I cleared the corrupted build artifacts:
rm -rf node_modules .next pnpm-lock.yaml
pnpm install
pnpm dev
The middleware error disappeared. The code hadn't changed at all — the environment was just broken.
How to Diagnose This in the Future
If you encounter EvalError: Code generation from strings disallowed for this context in Next.js middleware, here's a diagnostic checklist:
First, verify the obvious. Check your middleware imports and make sure you're not pulling in Payload, database clients, or Node.js APIs. If your imports look clean, move on.
Second, check if Node itself is working. Run a simple command:
node --version
If you get a dyld error or anything other than a clean version number, your Node installation is broken at the system level.
Third, check for version manager conflicts. Run these commands:
which node
which npm
which pnpm
If they point to different installations (some to Homebrew, some to nvm, some to volta), you have a PATH conflict that needs resolution.
Fourth, look for warning signs in the Next.js output. The non-standard NODE_ENV value warning I saw was actually a hint that something was wrong with my environment, not my code.
When debugging Edge Runtime errors, if your code checks out clean, zoom out and question the environment itself. Node version, package manager, OS-level dependencies, and Docker setups can all cause misleading errors.
Lessons Learned
The EvalError: Code generation from strings disallowed for this context message is technically accurate — something in the build chain was trying to use dynamic code generation. But the root cause wasn't my middleware code importing the wrong package. It was a broken Node binary that couldn't properly compile the middleware bundle in the first place.
Error messages point you toward symptoms, not always causes. When the obvious debugging path leads nowhere, step back and verify your foundational tools are actually working.
This is especially true on macOS with Homebrew, where running brew upgrade or setting up Docker tools can silently break native library linkages. If you're mixing Homebrew-installed Node with version managers like nvm, fnm, or volta, you're setting yourself up for exactly this kind of chaos.
Pick one Node version manager, keep it clean, and save yourself an hour of debugging middleware code that was never the problem.
Let me know in the comments if you've hit similar environment issues, and subscribe for more practical development guides.
Thanks, Matija