Claude Code 错误诊断指南:从日志到回归测试
用 Claude Code 从日志诊断到最小复现、回归测试和验证,建立可交付的错误排查流程。
错误诊断不是看见终端最后一行红字就凭感觉修改。真正的诊断,是把一次失败整理成别人、测试工具和 Claude Code 都能重复验证的证据。
先记住三个基础词。日志是命令或应用输出的记录。堆栈跟踪是错误发生前调用过哪些函数的路径。最小复现是删掉无关页面、数据和配置后,仍然能触发同样失败的小例子。
如果只对 Claude Code 说“帮我修复”,它可能会给出范围过大的修改。更好的做法是交给它失败命令、第一条失败信息、有限的原因假设,以及修复后必须通过的验证命令。本文把这个过程整理成适合新手使用、也能在团队中落地的流程。
延伸阅读可以参考 Claude Code 构建错误排查循环、Claude Code 错误信息解读 和 Claude Code Bug 报告模板。
诊断流程图
flowchart LR
A["保存失败命令"] --> B["找到第一条失败行"]
B --> C["限制为三个假设"]
C --> D["创建最小复现"]
D --> E["添加回归测试"]
E --> F["做最小修复"]
F --> G["用同一命令验证"]
G --> H["写交接记录"]
这个顺序的价值在于避免“先改再说”。Claude Code 能阅读很多文件,如果指令太宽,它可能顺手重构无关代码。错误诊断的目标不是增加修改量,而是缩小原因范围。
先收集四类证据。
| 证据 | 用途 | 可以给 Claude Code 的例子 |
|---|---|---|
| 失败命令 | 固定复现入口 | npm run build、node --test |
| 第一条失败行 | 避免日志尾部噪音 | TypeError、ERR_MODULE_NOT_FOUND |
| 运行环境 | 区分环境差异 | Node.js 版本、OS、CI 平台 |
| 期望行为 | 定义正确修复 | null 转成空数组、404 不重试 |
JavaScript 错误名称可以查 MDN JavaScript error reference。Node.js 项目要看 Node.js Errors docs,尽量使用 error.code 这类稳定字段,而不是只依赖可能变化的文字消息。E2E 测试失败时,Playwright Debugging Tests 的 Inspector、Trace Viewer 和 VS Code 调试比单看日志更可靠。
Claude Code 的实务工作流
可以把下面的提示词作为一次完整诊断任务。
claude -p "
Diagnose the following error.
1. Confirm the failing command
2. Separate the first failure from unrelated log noise
3. List up to three root-cause hypotheses
4. Create a minimal reproduction
5. Add a regression test
6. Apply the smallest fix
7. Verify with the same command and write a handoff note
Constraints:
- Do not perform unrelated refactors
- Explain any public API change before making it
- Do not call the fix complete if verification still fails
"
“最多三个假设”很重要。十个假设只会让调查失焦。比如 Cannot read properties of undefined,常见原因通常是 API 结构变化、初始值缺失,或异步数据准备好之前就渲染。
用例1:React 的 undefined 错误
常见场景是 API 返回 null,组件却调用了 users.map(...)。表面看是 React 渲染错误,根因往往是数据形状没有被规范化。
// user-list.mjs
export function names(users) {
if (!Array.isArray(users)) {
return [];
}
return users.map((user) => user.name ?? "(no name)");
}
// user-list.test.mjs
import assert from "node:assert/strict";
import test from "node:test";
import { names } from "./user-list.mjs";
test("names returns an empty array when the API returns null", () => {
assert.deepEqual(names(null), []);
});
test("names keeps valid user names", () => {
assert.deepEqual(names([{ name: "Masa" }]), ["Masa"]);
});
node --test user-list.test.mjs
如果旧代码只有 return users.map(...),第一个测试会失败。让 Claude Code 先添加失败测试,再做最小修复。很多时候,一个输入规范化函数就够了,不需要重写整个状态管理。
用例2:Node.js 的 ENOENT 和导入失败
ENOENT 通常表示找不到文件或目录。陷阱是 config/local.json 在本机存在,但没有进入 CI 或 Docker 镜像。
排查顺序是失败命令、error.code、error.path、Dockerfile 的 COPY、.gitignore、CI 的 working directory。提示词可以这样写。
claude -p "
Diagnose this Node.js ENOENT failure.
Inspect error.code, error.path, current working directory, Dockerfile, and CI config.
Suggest only fixes that do not depend on a local-only file.
"
不要停在“创建缺失文件”。如果配置是必需的,就在启动时给出清晰错误。如果是可选的,就提供默认值。如果 CI 需要样例配置,就在设置阶段复制仓库中的 sample 文件。
用例3:只在 CI 失败的 Playwright 测试
Playwright 的 timeout 可能来自应用 bug、等待条件错误、CI 机器更慢、登录过期或网络差异。只增加 timeout 经常只是掩盖问题。
先保留失败时的 trace。
// playwright.config.ts
import { defineConfig } from "@playwright/test";
export default defineConfig({
use: {
screenshot: "only-on-failure",
trace: "retain-on-failure",
video: "retain-on-failure",
},
});
把失败的 spec、locator、预期页面状态、trace 路径和 CI 命令交给 Claude Code。指令要明确:“增加 timeout 之前,请先区分 UI 状态、API 响应、认证和 locator 问题。”这样修复才不会变成简单等待。
用例4:TypeScript 连锁错误
二十个类型错误不一定是二十个 bug。很多时候,一个 API 类型变化会造成一串派生错误。
npx tsc --noEmit --pretty false 2>&1 | tee tsc.log
claude -p "
Read tsc.log and choose the first type error to fix.
Separate derived errors from the likely root cause.
After the fix, verify with npx tsc --noEmit --pretty false.
"
不要一次性修全部。先修根类型,重新运行同一命令,再看剩下的错误。这个小循环能减少不必要的 as any。
先给日志做粗分类
下面的小脚本可以直接运行,用来在深入分析前判断日志大类。
// triage-log.mjs
import fs from "node:fs";
const sample = `
TypeError: Cannot read properties of undefined (reading 'map')
at ProductList (src/ProductList.tsx:42:18)
`;
const input = process.argv[2]
? fs.readFileSync(process.argv[2], "utf8")
: sample;
const rules = [
[/ERR_MODULE_NOT_FOUND|Cannot find module/i, "dependency or import path"],
[/ENOENT/i, "file path or working directory"],
[/TypeError:.*undefined|Cannot read properties/i, "data shape or initial value"],
[/Timeout.*expect|locator/i, "E2E wait condition or screen state"],
[/TS\d{4}/, "TypeScript type error"],
];
const matches = rules
.filter(([pattern]) => pattern.test(input))
.map(([, label]) => label);
console.log(matches.length ? matches.join("\n") : "Unclassified: inspect first failure");
node triage-log.mjs
node triage-log.mjs tsc.log
它不是万能诊断器,只是帮助你在对话前分清依赖、路径、数据形状、E2E 等待和 TypeScript 类型错误。
可复现 Bug 报告模板
让 Claude Code 调查前,先把问题整理成这种格式。如果团队使用 GitHub Issues,可以用官方 GitHub issue forms syntax 做成表单。
## Summary
Describe the broken behavior in one sentence.
## Failed command
`npm run build`
## Expected result
The build succeeds and creates `dist/`.
## Actual result
The command fails with `TypeError: Cannot read properties of undefined`.
## First failing line
`src/components/ProductList.tsx:42:18`
## Reproduction steps
1. `npm ci`
2. `npm run build`
## Environment
- Node.js: 22.x
- OS: Windows 11 / GitHub Actions ubuntu-latest
- Branch: feature/product-list
## Already tried
- Regenerated lockfile
- Checked API response fixture
## Verification after fix
- `node --test`
- `npm run build`
关键不是“它坏了”,而是“按这些步骤会稳定复现同一个失败”。
常见失败模式
第一,只贴日志最后一行。最后一行只是进程停止的位置,不一定是根因。保留第一条失败和前后相关日志。
第二,用错误消息文字做分支。Node.js 中尽量使用 error.code 或 name 等更稳定字段。
第三,不做最小复现。在完整页面或完整生产配置里调试,很难判断修复是否真的命中原因。
第四,没有回归测试。没有测试的修复,会在下一次重构中悄悄回来。
第五,给 Claude Code 的范围太大。要求“让这个具体失败通过的最小修改”,而不是“顺便清理相关文件”。团队评审边界可以参考 Claude Code 评审工作流清单。
写交接记录
验证命令通过后,给评审者和未来的自己留一段短记录。
## Diagnosis note
- Failure: `npm run build`
- Cause: `users.map` was called when the API returned null
- Fix: Normalize non-array input to an empty array in `names()`
- Regression test: `node --test user-list.test.mjs`
- Verification: `npm run build` passed
- Remaining risk: Confirm separately whether API null is intentional
claude -p "
Write a Markdown diagnosis note for this fix.
Include cause, changed files, regression test, verification command,
and remaining risk. Keep it short enough for a reviewer to read in five minutes.
"
模板与咨询
个人项目可以直接复制本文命令和模板。团队使用时,还要规定哪些日志可以分享、哪些密钥不能粘贴到 Claude Code、最小复现放在哪里、CI 必须保留哪些 artifact,以及评审需要哪些验证证据。
ClaudeCodeLab 提供 Claude Code 产品与模板 和 Claude Code 培训与咨询,可以帮助团队把 Bug 报告表单、CI 排查提示词、回归测试模式和交接记录标准化,而不是每次临时救火。
Masa 在 ClaudeCodeLab 维护中试用这套流程后,最明显的收益来自三个习惯:保留第一条失败行、创建最小复现、修复后运行同一个命令。Claude Code 的建议不再只是“看起来合理”,而是每次都附带证据、假设、测试和验证结果。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
Claude Code权限安全阶梯:逐步放开访问而不失控
从只读到有限编辑、验证命令和部署检查的 Claude Code 权限升级流程。
Claude Code 小PR证据包:让小改动真正可审查
用差异、验证命令、公开URL、CTA路径和回滚说明,把Claude Code的小PR变得可审查。
Claude Code 提交前 Review Gate:同时检查差异、测试、公开 URL 和 CTA
提交前用 Claude Code 审查差异范围、build、公开 URL、Gumroad 链接、咨询 CTA、缺少测试和无关文件。