# 如何修复AI忘记环境变量验证

> AI代理直接读取process.env值而不进行验证，在环境变量缺失时导致静默的undefined错误，并且缺少启动时的错误提示。

**Type:** Failure  
**Tools:** Cursor, Claude Code, Codex, Windsurf  
**Stack:** Next.js, TypeScript, Cloudflare  
**Updated:** 2026-06-08

---

代理直接访问 `process.env.SOME_KEY`，因此当变量缺失时，应用会在静默状态下启动并出错 — 没有崩溃，没有警告，只是`undefined`流入业务逻辑。

## 症状

原始的`process.env`读取分散在代码库中，没有模式、类型安全或启动时的断言。

```ts
// lib/stripe.ts — WRONG
import 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模式在启动时验证所有必需的环境变量，这样进程在服务任何请求之前就会以清晰的错误信息崩溃。

```ts
// lib/env.ts — CORRECT
import { 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
```

```ts
// 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",
});
```

```txt
[ ] 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
```

## 修复提示

```txt title="Fix Prompt"
Every raw process.env access in this file is unvalidated. Create a lib/env.ts
module that parses and validates all required environment variables with Zod at
startup. Replace every process.env.FOO reference in the codebase with the
typed env.FOO import. Add a .env.example file listing every variable with a
placeholder value and comment.
```

## 测试

```bash
# Find any remaining raw process.env reads outside of lib/env.ts
grep -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"
```