如何修复AI忘记环境变量验证
AI代理直接读取process.env值而不进行验证,在环境变量缺失时导致静默的undefined错误,并且缺少启动时的错误提示。
CursorClaude CodeCodexWindsurf Next.jsTypeScriptCloudflare
代理直接访问 process.env.SOME_KEY,因此当变量缺失时,应用会在静默状态下启动并出错 — 没有崩溃,没有警告,只是undefined流入业务逻辑。
症状
原始的process.env读取分散在代码库中,没有模式、类型安全或启动时的断言。
// lib/stripe.ts — WRONGimport Stripe from "stripe";
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: "2024-06-20",});// If STRIPE_SECRET_KEY is undefined, Stripe SDK accepts it and every// charge silently fails at runtime instead of at startup.发生原因
代理为了简洁和快速达到可用代码而优化。环境变量验证是样板代码,在大多数训练示例中并不出现,因此模型会跳过它直接进行集成。
如何识别
process.env.FOO在使用时没有非空断言或回退检查。- 项目中不存在
env.ts/env.mjs验证文件。 - 在调用处,环境变量值的TypeScript类型为
string | undefined。 - 即使
.env.local为空,应用也能无错误启动。
如何修复
使用Zod模式在启动时验证所有必需的环境变量,这样进程在服务任何请求之前就会以清晰的错误信息崩溃。
// lib/env.ts — CORRECTimport { z } from "zod";
const envSchema = z.object({ STRIPE_SECRET_KEY: z.string().min(1), DATABASE_URL: z.string().url(), NEXTAUTH_SECRET: z.string().min(32), NODE_ENV: z.enum(["development", "production", "test"]).default("development"),});
export const env = envSchema.parse(process.env);// ^^^^^ throws at startup if any var is missing// lib/stripe.ts — CORRECT (import validated env)import Stripe from "stripe";import { env } from "@/lib/env";
export const stripe = new Stripe(env.STRIPE_SECRET_KEY, { apiVersion: "2024-06-20",});[ ] Create lib/env.ts with a Zod schema covering every required variable[ ] Import env from lib/env everywhere — never use process.env directly[ ] Add lib/env.ts to the module graph so it runs at server startup (import in next.config.ts)[ ] Document all variables in .env.example with placeholder values[ ] Use z.string().url() / z.string().min(n) for format constraints, not just presence修复提示
Every raw process.env access in this file is unvalidated. Create a lib/env.tsmodule that parses and validates all required environment variables with Zod atstartup. Replace every process.env.FOO reference in the codebase with thetyped env.FOO import. Add a .env.example file listing every variable with aplaceholder value and comment.测试
# Find any remaining raw process.env reads outside of lib/env.tsgrep -rn "process\.env\." --include="*.ts" --include="*.tsx" . \ | grep -v "lib/env.ts" \ | grep -v "next.config" \ | grep -v "node_modules" \ && echo "FAIL: raw process.env reads found" || echo "OK"