速查向。每条:报错原文 → 中文释义 → 最小复现 → 根因 → 修复 → 进阶。 AI 协作时,把报错原文 + 对应条目链接贴过去比转述高效得多。
目录
Python
1. ModuleNotFoundError: No module named 'X'
释义:sys.path 找不到这个包。
根因:四种之一
- 没装(
pip install漏了或装到别的解释器)。 - 装在了 user site,但当前用 venv。
- 自己写的包,但
sys.path不含项目根(src layout 常见)。 - 包名和导入名不一致(
pip install beautifulsoup4→import bs4)。
诊断
python -c "import sys; print(sys.path)" # path 里有没有项目根
python -c "import X; print(X.__file__)" # 它装在哪儿
which python && python -m pip list | grep X # 解释器 + 装了没
修复
# 解释器对不上
python -m pip install X # 用当前解释器装
# src layout
echo '[tool.pytest.ini_options]\npythonpath=["src"]' >> pyproject.toml
# 开发模式装自己
pip install -e .
2. ImportError: attempted relative import with no known parent package
释义:from .foo import bar 但脚本作为入口直接跑,Python 不知道它属于哪个包。
复现
python mypkg/script.py # ❌ 直接当脚本跑,没有 parent package
python -m mypkg.script # ✅ 作为模块跑
修复:用 -m 跑,或改成绝对导入 from mypkg.foo import bar。
原理:Python 用 __package__ 解析相对导入,直接跑脚本时 __package__ 是空字符串。
3. ImportError: cannot import name 'X' from partially initialized module 'Y'
释义:循环导入,模块 Y 在被初始化的中途又被 import 了。
复现
# a.py
from b import bb
def aa(): return bb()
# b.py
from a import aa # 💥 a 还没执行完,bb 还没定义
def bb(): return aa()
修复(按优先级)
-
重新设计,把公共部分抽到第三个模块。
-
把 import 推迟到函数内:
def bb(): from a import aa return aa() -
改成模块级 import,函数里取属性:
import a def bb(): return a.aa()
4. TypeError: 'NoneType' object is not subscriptable / ... is not iterable / ... has no attribute X
释义:函数返回了 None,你拿来当 list/dict/object 用。
根因:函数某条分支隐式 return None。
def find(x):
if x > 0:
return [1, 2, 3]
# else 隐式 return None
print(find(-1)[0]) # 💥
修复:加类型注解 + 静态检查器(mypy / pyright),编译期暴露。
def find(x: int) -> list[int]: # 强制必须返回 list
return [1, 2, 3] if x > 0 else []
pyright --strict 或 mypy --strict 会拒绝隐式 None。
5. UnicodeDecodeError: 'utf-8' codec can't decode byte 0xXX in position N
释义:按 UTF-8 读,但文件不是 UTF-8(常见 GBK/GB18030/Latin-1)。
修复
# 知道编码
open(path, encoding="gbk")
# 不知道编码 — 嗅探
import chardet
with open(path, "rb") as f:
enc = chardet.detect(f.read(4096))["encoding"]
# 不在乎编码错误
open(path, encoding="utf-8", errors="replace") # 替换为 U+FFFD
open(path, encoding="utf-8", errors="ignore") # 丢弃
Windows 坑:open() 默认编码是系统 ANSI(中文 Win 是 GBK),Linux/Mac 是 UTF-8 → 同一份代码跨平台行为不同。永远显式传 encoding。
6. RuntimeError: dictionary changed size during iteration
复现
for k in d:
if d[k] is None: del d[k] # 💥
修复
for k in list(d): # 快照 keys
if d[k] is None: del d[k]
d = {k: v for k, v in d.items() if v is not None} # 重建
set 同样有此问题(Set changed size during iteration)。
7. RecursionError: maximum recursion depth exceeded
根因:CPython 默认递归上限 1000,真的递归这么深通常说明算法该改迭代。
诊断:看 stack trace 是否真的有意义的深栈,还是无限递归。
import sys; print(sys.getrecursionlimit())
sys.setrecursionlimit(10000) # 临时调高,但通常治标不治本
根治:改迭代 + 显式栈,或者尾递归手动展开。
def walk_iter(root):
stack = [root]
while stack:
node = stack.pop()
...
stack.extend(node.children)
8. RuntimeWarning: coroutine 'X' was never awaited
复现
async def f(): return 1
f() # ❌ 创建 coroutine 对象就扔了
修复
await f() # 在另一个 async 里
asyncio.run(f()) # 顶层入口
asyncio.create_task(f()) # 后台跑,但记得保留引用避免被 GC
坑:create_task 返回的 task 必须保留引用,否则 GC 可能回收,task 静默消失。常用模式:
tasks = set()
t = asyncio.create_task(f())
tasks.add(t)
t.add_done_callback(tasks.discard)
9. asyncio.TimeoutError / TimeoutError
Python 3.11 起,asyncio.TimeoutError = 内建 TimeoutError(子类)。
try:
async with asyncio.timeout(5): # 3.11+,推荐
await long_call()
except TimeoutError:
...
3.10 及更早用 asyncio.wait_for(coro, 5)。
10. RuntimeError: Event loop is closed / ... already running
释义:在已关闭/已运行的 loop 上调度任务。
常见场景:
- Jupyter / pytest 中已经有 loop,又调
asyncio.run()。 - 多线程,主线程关 loop,worker 还在 schedule。
修复
# Jupyter
import nest_asyncio; nest_asyncio.apply()
# 或检查再决定
try:
loop = asyncio.get_running_loop()
loop.create_task(f())
except RuntimeError:
asyncio.run(f())
11. pip install 报 error: Microsoft Visual C++ 14.0 or greater is required
Windows 专属:某些包(lxml、psycopg2、Cython 编译)需要本地编译,缺 MSVC。
修复(任一)
- 装 Build Tools for Visual Studio,选 "Desktop development with C++"。
- 找预编译 wheel,或换 binary 包(
psycopg2-binary替代psycopg2)。 - 升级 pip,经常老 pip 找不到新的 wheel:
python -m pip install -U pip。
12. ssl.SSLCertVerificationError: ... certificate verify failed
释义:HTTPS 握手时,本地不信任服务器证书。
根因
- 公司 MITM 代理(防火墙拆 TLS)。
- 系统 CA 包过期(老镜像)。
- macOS Python 默认不用系统 keychain,需要装 Python.org installer 自带的
Install Certificates.command。
修复
# macOS
/Applications/Python\ 3.x/Install\ Certificates.command
# 公司代理:把代理 CA 加到 certifi
pip config set global.cert /path/to/corp-ca.pem
python -c "import certifi; print(certifi.where())"
# 急救(不要长期用):
import ssl; ctx = ssl._create_unverified_context()
13. pip 装包慢 / 卡死 / hash mismatch
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple X # 国内镜像
pip install --no-cache-dir X # 缓存可能坏了
pip install --index-url https://... --trusted-host ... # HTTPS 出问题
锁版本:
pip install pip-tools
pip-compile requirements.in -o requirements.txt
pip-sync requirements.txt # 严格按 lockfile
或直接上 uv:
uv pip install -r requirements.txt # 比 pip 快 10-100x
14. TypeError: __init__() got an unexpected keyword argument 'X'
释义:你传的关键字参数,目标函数签名里没有。
最常见来源
- 升级了库,旧参数被改名/删除。
- pydantic v1 → v2,
Config嵌套类改model_config。 - pandas 版本不同 API 不同。
诊断
import inspect
print(inspect.signature(SomeClass.__init__)) # 看真实签名
修复:对齐文档版本,或锁老版本继续用。
15. pydantic / dataclass 互不兼容
@dataclass
class A: x: int
class B(BaseModel): x: int
a: A = B(x=1) # ❌ 类型上无关联
经验:整个项目挑一种用,别混。FastAPI/SQLModel 选 pydantic;无 web 框架的纯数据选 dataclass(零依赖,启动快)。
16. OSError: [Errno 24] Too many open files
根因:文件/socket 没关。
诊断
lsof -p <PID> | wc -l # 看具体打开数
ulimit -n # 当前 soft limit
修复
# 永远用 context manager
with open(path) as f: ...
# requests session 复用,不要每次 requests.get(...)
session = requests.Session()
# httpx async
async with httpx.AsyncClient() as client: ...
调高 ulimit 只是临时方案:ulimit -n 65536。
17. ImportError: DLL load failed while importing X(Windows)/ dyld: Library not loaded(Mac)
释义:Python 扩展包的原生动态库找不到/不兼容。
常见原因
- 装了 arm64 wheel 但 Python 是 x86(M1 Mac)。
- Visual C++ Runtime 缺(Windows)。
- Conda 和 pip 混装同一个包,版本/链接对不上。
修复
python -c "import platform; print(platform.machine())" # arm64 vs x86_64
# 卸载重装匹配架构的
pip uninstall X
pip install X --no-cache-dir
# Conda 用户尽量用 conda 装 native 包,别混 pip
18. decimal.InvalidOperation / float 累积误差
0.1 + 0.2 == 0.3 # False
修复
from decimal import Decimal
Decimal("0.1") + Decimal("0.2") == Decimal("0.3") # True
# 或者比较时用 tolerance
import math
math.isclose(a, b, rel_tol=1e-9)
金额永远用 Decimal,不要用 float。
TypeScript
1. TypeError: Cannot read properties of undefined (reading 'X')
释义:访问 undefined 的属性。最高频运行时错。
修复
// 可选链 + 默认值
const name = user?.profile?.name ?? "anonymous";
// strictNullChecks 编译期暴露
// tsconfig.json: "strict": true
别用:! 非空断言糊弄运行时,它只骗 TS 不骗 JS。
2. TypeError: X is not a function
根因(按概率)
-
拼错了(
.fitlervs.filter)。 -
循环依赖导致 import 拿到 undefined。
-
默认导出 vs 命名导出搞混:
// bar.ts: export default function bar(){} import { bar } from "./bar"; // ❌ bar 是 undefined import bar from "./bar"; // ✅ -
用了不该用的 CJS/ESM 互操作(下方专门一节)。
3. ReferenceError: X is not defined
90% 是拼写错误或忘记 import。剩下 10%:
-
浏览器代码引用 Node API(
process、Buffer、__dirname)。 -
顶层
await在 CommonJS 文件。 -
用
let/const声明前访问(TDZ):console.log(x); // ReferenceError const x = 1;
4. Cannot use import statement outside a module
根因:Node 把文件当 CJS 解析,但里面是 ESM 语法。
修复(任一)
package.json加"type": "module",所有.js当 ESM。- 文件后缀改
.mjs(ESM)或.cjs(CJS)。 - 构建产物里 import 不带后缀:在
tsconfig设"moduleResolution": "bundler",或加.js后缀。
TS 特别坑:tsc 不会自动加 .js 后缀,但 Node ESM 强制要求。所以 TS 源码里要写:
import { foo } from "./bar.js"; // ✅ 是的,TS 源也写 .js
或用 "moduleResolution": "bundler"(Vite/webpack 等打包器场景)。
5. TS:Type 'X' is not assignable to type 'Y'
修复策略(按推荐顺序)
- 改类型反映真实数据。
- 类型守卫收窄:
if (typeof x === "string")/if (x instanceof Date)/if ("foo" in x)。 - discriminated union +
switch (x.kind)。 - 最后才用
as Y。as unknown as Y是代码异味,几乎 100% 说明类型设计有问题。
type Result = { ok: true; value: number } | { ok: false; error: string };
function handle(r: Result) {
if (r.ok) console.log(r.value); // 自动收窄
else console.error(r.error);
}
6. TS:Object is possibly 'undefined' / 'null'
const u = users.find(u => u.id === 1);
console.log(u.name); // ❌
if (!u) throw new Error("not found");
console.log(u.name); // ✅ 收窄
users.find(...)?.name; // ✅ 可选链
7. TS:Property 'X' does not exist on type '{}'
通常是 JSON.parse / 外部 API 返回被推断成 {} 或 any。
const u = JSON.parse(s) as User; // 不安全,运行时不校验
// 推荐:runtime schema 校验
import { z } from "zod";
const UserSchema = z.object({ id: z.number(), name: z.string() });
const u = UserSchema.parse(JSON.parse(s)); // 失败时 throw,字段类型有保证
库选择:zod(生态最大)、valibot(体积小)、arktype(性能/语法新)。
8. TS:Excessive stack depth comparing types / 编译变慢
复杂条件类型/递归类型导致 TS 类型检查指数爆炸。
诊断
tsc --extendedDiagnostics # 看哪个文件慢
tsc --generateTrace ./trace # 火焰图
修复
- 复杂类型拆小,中间用
type Alias = ...缓存。 - 用
infer时加深度限制:T extends [infer Head, ...infer Tail]替代递归无限层。 - 必要时手动写类型,放弃类型推导(
as Foo)。
9. TS:exports is not defined in ES module scope(打包后)
打包器把 CJS 代码塞进 ESM 文件,运行时炸。常见于:
- 一个依赖是 CJS,但被
import进 ESM,且 bundler 配置不当。 tsconfig的"module"和打包器输出对不齐。
修复:用 Vite/esbuild/Rollup 的 CJS 插件,或锁定依赖只用 ESM 版本(看 package.json 的 exports)。
10. Module not found: Can't resolve 'X'(webpack/vite/esbuild)
checklist
npm install漏了。- 大小写:
./Uservs./user,Mac/Win 不区分但 Linux/CI 区分。 tsconfig.json的paths别名没在打包器同步配置(vite 需要vite-tsconfig-paths,webpack 需要tsconfig-paths-webpack-plugin)。- monorepo 里 workspace 包没 build,引用的是
dist/不存在。
11. Type instantiation is excessively deep and possibly infinite
递归类型出问题。
type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> }; // OK
type Bad<T> = Bad<{ x: T }>; // 💥
修复:加深度计数器
type DeepPartial<T, D extends number = 5> =
D extends 0 ? T :
T extends object ? { [K in keyof T]?: DeepPartial<T[K], Prev<D>> } : T;
或重新设计——一般不需要这么深。
12. 'this' implicitly has type 'any'
类方法里 this 上下文丢失,通常是 callback 没绑定:
class Foo {
name = "x";
log() { console.log(this.name); }
}
const f = new Foo();
setTimeout(f.log, 100); // ❌ this 是 undefined
setTimeout(() => f.log(), 100); // ✅ 箭头保留 this
setTimeout(f.log.bind(f), 100); // ✅
类字段写成箭头函数也行(代价:每个实例一份函数):
class Foo { log = () => console.log(this.name); }
13. tsconfig 配错导致类型不严格
最少应该开:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true
}
}
noUncheckedIndexedAccess 让 arr[i] 变 T | undefined,强烈建议开——能消除大量越界 bug。
14. 升级 TS 后大量报错
# 先看完整变更
tsc --noEmit
# 临时降版本/锁版本调试
npx typescript@5.4 --noEmit
# 暂时静音,加 issue 跟踪
// @ts-expect-error: 升级 TS 5.5 后报错,见 issue #123
@ts-expect-error 优于 @ts-ignore——错误消失时它会报错,提醒你删掉。
15. ESLint vs Prettier 冲突
npm i -D eslint-config-prettier # 关掉 ESLint 里所有格式规则
# .eslintrc
{ "extends": ["...", "prettier"] } # prettier 必须在最后
让 Prettier 管格式,ESLint 管 bug——分工清楚。
Node.js
1. EADDRINUSE: address already in use :::3000
释义:端口被占。
诊断 + 杀
# Linux / Mac
lsof -i :3000
kill -9 <PID>
# Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /F
避免:开发环境用 nodemon / tsx watch,关进程时确保子进程也终止(process.on('SIGTERM', () => server.close()))。
2. ENOENT: no such file or directory
根因 #1:相对路径,但 cwd 不是你以为的目录。
// ❌ 依赖运行时 cwd
fs.readFileSync("./config.json");
// ✅ 相对于当前文件
import { fileURLToPath } from "node:url";
import path from "node:path";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
fs.readFileSync(path.join(__dirname, "config.json"));
根因 #2:打包后路径 dist/ 和源码 src/ 结构不同,相对路径失效 → 用 import.meta.url + Vite 的 ?raw/?url 资源导入。
3. EACCES: permission denied
文件权限不够。常见:
- Linux/Docker 里以非 root 运行,但挂载卷的 owner 是 root。
- npm 全局装包到
/usr/local,需 sudo。
修复
chmod +x script.js # 可执行
chown -R $USER:$USER ./node_modules
# 别用 sudo npm install,改 prefix
npm config set prefix ~/.npm-global
4. EMFILE: too many open files
诊断
ulimit -n # 当前 limit
lsof -p <PID> | wc -l # 实际打开
修复
ulimit -n 65536 # 临时
代码层面:
// 限制并发
import pLimit from "p-limit";
const limit = pLimit(10);
await Promise.all(items.map(it => limit(() => processItem(it))));
// stream 必须 destroy / close
import { pipeline } from "node:stream/promises";
await pipeline(input, transform, output); // 自动清理
5. MaxListenersExceededWarning: Possible EventEmitter memory leak
某个 EventEmitter 加了 > 10 个 listener,通常循环里反复 .on() 没 .off()。
// ❌ 每次 req 加一个 listener,内存泄漏
app.on("close", () => cleanup()); // 在 handler 里
// ✅ 启动时一次
emitter.once("event", handler); // 一次性
emitter.removeListener("event", handler);
emitter.setMaxListeners(20); // 真的需要更多时,显式调高
别用 setMaxListeners(0)(无限),那是把警告关掉,泄漏还在。
6. UnhandledPromiseRejection → Node 15+ 默认 crash
async function main() { throw new Error("x"); }
main(); // ❌ 没 catch,进程退出
main().catch(console.error); // ✅
顶层兜底:
process.on("unhandledRejection", (err) => {
logger.error("unhandled", err);
// 决定:gracefully exit 还是继续
});
process.on("uncaughtException", (err) => {
logger.fatal("uncaught", err);
process.exit(1); // uncaught 必须退出,状态已不一致
});
7. Error: write EPIPE
向已关闭的 stream 写。最常见:管道下游(| head、| grep -m1)提前退出。
process.stdout.on("error", (err) => {
if ((err as NodeJS.ErrnoException).code === "EPIPE") process.exit(0);
});
CLI 工具必加这段,不然 mycli | head 就崩。
8. Error: connect ECONNREFUSED 127.0.0.1:5432
服务没起 / 端口错 / 防火墙挡 / Docker 网络配错。
诊断
# 服务在不在
nc -zv 127.0.0.1 5432
ss -tlnp | grep 5432 # Linux,看监听
# Docker:容器之间用服务名,不是 localhost
# docker-compose.yml: app 里连 db,host 写 "db",不是 "localhost"
9. Error: connect ETIMEDOUT
不同于 ECONNREFUSED:服务可能在但网络不通(防火墙、安全组、VPN)。
诊断
traceroute <host>
mtr <host> # 持续监测
curl -v --connect-timeout 5 http://host:port
代码层加超时,别让 fetch 默认无限等:
const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
10. RangeError: Invalid string length / Maximum call stack size exceeded
-
第一个:字符串拼接超过 ~512MB(V8 限制)。改用 stream。
-
第二个:递归过深或循环引用。诊断:
const seen = new WeakSet(); function check(o: object) { if (seen.has(o)) throw new Error("cycle"); seen.add(o); // ... }
JSON.stringify 遇到循环引用就抛此错。用 util.inspect(obj, { depth: 3 }) 调试。
11. JavaScript heap out of memory
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
临时
node --max-old-space-size=4096 script.js # 默认约 1.7G,调高到 4G
NODE_OPTIONS=--max-old-space-size=4096 npm test
根治:找泄漏。
node --inspect script.js # Chrome devtools 接入
# 拍堆快照:devtools → Memory → Heap snapshot,对比两次找增量
常见泄漏:全局 Map/Set 只 add 不 delete、闭包持有大对象、setInterval 没 clear、Promise 链上保留过多状态。
12. npm ERR! ERESOLVE unable to resolve dependency tree
peer dependency 冲突。
解法优先级
-
升级老依赖到兼容新 peer 的版本。
-
package.json加overrides(npm 8+)/resolutions(yarn)/pnpm.overrides:{ "overrides": { "react": "18.2.0" } } -
最后才
--legacy-peer-deps(把问题藏起来,迟早爆)。
13. Error: Cannot find module 'X'(运行时)
原因:
- 没装(
npm ci漏了 /node_modules删了)。 - 在 dev 装但 prod 跑(
devDependencies里)。 - TS 编译输出指向
dist/,但运行的是src/(或反过来)。 - monorepo 里 workspace 包没 build。
node --trace-warnings index.js # 看哪儿引起的
node -e "console.log(require.resolve('X'))" # 它能找到吗
14. (node:XX) ExperimentalWarning: ... is an experimental feature
node --no-warnings script.js # 关全部 warning(粗暴)
NODE_OPTIONS=--no-warnings=ExperimentalWarning npm start
更细粒度:process.on("warning", w => { if (...) return; ... })。
15. tsx / ts-node ESM import 报错
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"
修复:用 tsx 替代 ts-node。tsx 默认支持 ESM、TS、JSX,几乎零配置:
npx tsx script.ts # 一次
npx tsx watch script.ts # 监听
{ "scripts": { "dev": "tsx watch src/index.ts" } }
16. Error: getaddrinfo ENOTFOUND <host>
DNS 解析失败。Docker 里特别常见:容器没配置 DNS,或 host 写错(localhost vs 服务名)。
诊断
node -e "require('dns').resolve('host', console.log)"
docker exec <container> getent hosts <host>
17. npm 锁文件冲突
-
package-lock.json在 merge 时冲突——不要手动改,以一边为基准,然后npm install重新生成:git checkout --theirs package-lock.json npm install git add package-lock.json -
CI 必须
npm ci(严格按 lockfile),不要npm install(可能改 lockfile)。
Rust
1. cannot borrow X as mutable because it is also borrowed as immutable(E0502)
let mut v = vec![1, 2, 3];
let r = &v[0];
v.push(4); // 💥 push 可能 reallocate,r 悬空
println!("{}", r);
修复:缩短 immutable borrow 作用域,在 push 前用完 r。NLL(Non-Lexical Lifetimes)让借用作用域到最后一次使用,所以下面这个就过:
let mut v = vec![1, 2, 3];
let r = &v[0];
println!("{}", r); // r 在这里结束生命
v.push(4); // ✅
2. value borrowed here after move(E0382)
let s = String::from("x");
let t = s;
println!("{}", s); // 💥 s 已被 move 给 t
修复:三选一
let t = s.clone(); // 1. 复制(代价:堆复制)
fn take(s: &str) { ... } // 2. 改成引用,不取所有权
take(&s);
use std::rc::Rc;
let s = Rc::new(String::from("x")); // 3. Rc 共享所有权
let t = Rc::clone(&s);
线程间共享用 Arc(原子计数,跨线程安全)。
3. cannot move out of borrowed content / cannot move out of index of Vec(E0507)
fn f(v: &Vec<String>) -> String {
v[0] // 💥 不能 move 出借用的内容
}
修复
v[0].clone() // 复制一份
v.first().cloned().unwrap_or_default() // 优雅版
&v[0] // 返回引用,改签名 -> &String
std::mem::take(&mut v[0]) // 取走,留空默认值(需要 &mut)
4. cannot return reference to local variable(E0515)
fn f() -> &str {
let s = String::from("x");
&s // 💥 s 离开作用域被 drop
}
修复
fn f() -> String { String::from("x") } // 返回所有权
fn f<'a>(input: &'a str) -> &'a str { &input[..1] } // 返回入参的子引用
5. the trait bound 'X: Y' is not satisfied(E0277)
修复路径(按推荐)
-
加
#[derive(...)](标准 trait):#[derive(Debug, Clone, PartialEq, Eq, Hash)] struct Id(u64); -
手动
impl:impl Display for MyType { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "...") } } -
加 trait bound 到泛型签名:
fn foo<T: Display>(x: T)。 -
newtype 绕开 orphan rule:
struct Wrap(ExternalType); impl SomeTrait for Wrap { ... }。
6. mismatched types / expected X, found Y(E0308)
最常见子情况:
&strvsString:fn(&str)接String需要&s(deref coercion 通常自动,但泛型不行)。Vec<T>vs&[T]:fn(&[T])接Vec<T>需要&v。i32vsusize:索引必须usize,显式as usize(注意溢出)或用try_into()?。Result<T, E1>vsResult<T, E2>:用?时From<E2> for E1没实现 →thiserror/anyhow简化。
7. cannot find macro 'X' in this scope
宏需要 use 或 #[macro_use],或者 crate 没暴露宏。
use serde::{Serialize, Deserialize}; // proc macro,正常 use
use log::info; // declarative macro,2018+ 也用 use
8. expected struct 'X', found struct 'X'(同名不同 crate)
依赖图中同一 crate 出现两个版本,类型不互通。
cargo tree -d # 找重复
修复
# Cargo.toml
[patch.crates-io]
tokio = { version = "1" } # 强制所有 tokio 走这个版本
或显式升级依赖到兼容版本。
9. future cannot be sent between threads safely
async fn f() {
let rc = Rc::new(1); // Rc 非 Send
tokio::spawn(async move {
println!("{}", rc); // 💥 task 跨线程,捕获了非 Send
});
}
修复
let arc = Arc::new(1); // Arc 是 Send
tokio::spawn(async move { println!("{}", arc); });
std Mutex 跨 await 的坑:std::sync::Mutex 持有 guard 跨 .await 会死锁(同任务再请求自己持有的锁,但 runtime 可能调度走);async 场景用 tokio::sync::Mutex,或缩短持锁范围到不跨 await:
let value = {
let g = mutex.lock().unwrap();
g.compute() // 同步代码,scope 结束前 drop guard
}; // <- guard 在这里 drop
do_async(value).await; // 然后再 await
10. cannot infer type / type annotations needed(E0282/E0283)
let v = Vec::new(); // 💥 不知道 Vec<什么>
let v: Vec<i32> = Vec::new();
let v = Vec::<i32>::new();
let v = vec![1, 2, 3]; // 从字面量推
let x = "1".parse()?; // 💥 parse 成什么?
let x: i32 = "1".parse()?;
let x = "1".parse::<i32>()?;
11. borrow of moved value 在闭包里
let s = String::from("x");
let f = move || println!("{}", s);
f();
println!("{}", s); // 💥 s 已 move 进闭包
修复:let f = move || println!("{}", s.clone()); 或闭包前 clone 一份。
Fn/FnMut/FnOnce 的选择:闭包默认按需,move 强制取所有权(用于 spawn / 跨线程)。
12. lifetime 错误总集(E0106, E0621, ...)
最常见:struct 持有引用没标 lifetime:
struct S { name: &str } // ❌
struct S<'a> { name: &'a str } // ✅
返回引用没标:
fn longest(a: &str, b: &str) -> &str // ❌ 哪个的 lifetime?
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str // ✅
心法:lifetime 是给编译器证明"我这个引用不会比来源活得久"的标注,不影响运行时。
13. unresolved import 'crate::X' / could not find 'X' in the crate root
模块没声明:
// src/lib.rs 或 src/main.rs
mod foo; // 声明 src/foo.rs 或 src/foo/mod.rs
mod bar;
pub use foo::Bar;
子目录:
src/
lib.rs # mod net;
net/
mod.rs # pub mod tcp; pub mod udp;
tcp.rs
udp.rs
2018+ 也支持:
src/
lib.rs # mod net;
net.rs # pub mod tcp; pub mod udp;
net/
tcp.rs
udp.rs
14. index out of bounds: the len is N but the index is M(运行时 panic)
数组越界。Rust 不像 C 那样 UB,直接 panic,但仍是 bug。
避免
v[i] // panic
v.get(i) // Option<&T>,没就 None
v.get(i).copied().unwrap_or(0)
15. attempt to add with overflow(debug)/ 静默 wrap(release)
debug:溢出 panic;release:溢出 wrap(默认),不报错——这是真 bug 源。
let x: u8 = 200;
let y: u8 = 100;
let z = x + y; // debug panic,release 变 44
// 显式选择行为
x.checked_add(y) // Option<u8>
x.wrapping_add(y) // 显式 wrap
x.saturating_add(y) // 饱和(到 u8::MAX)
x.overflowing_add(y) // (result, bool)
或在 Cargo.toml release 也开 overflow check:
[profile.release]
overflow-checks = true
16. error[E0599]: no method named 'X' found for type 'Y'
原因
-
方法在某个 trait 上,没
use这个 trait:use std::io::Read; // 不 use 这个,Read trait 上的 read() 用不了 -
类型实际不一样(
&strvsString、Vecvs&[T])。 -
macro 展开后类型变了。
诊断:cargo doc --open 直接看类型的所有方法。
17. proc-macro derive 'X' not found in scope
use serde::Serialize; // 必须 use trait
#[derive(Serialize)] // 然后 derive
struct S;
或
#[derive(serde::Serialize)] // 全路径,免 use
struct S;
Cargo.toml 必须开启对应 feature:
serde = { version = "1", features = ["derive"] }
18. linker error / cannot find -lXXX
链接外部 C 库失败。
诊断
cargo build -vv # 看完整 link 命令
pkg-config --libs xxx
修复
# Ubuntu
sudo apt install libxxx-dev pkg-config
# Mac
brew install xxx
# Windows:vcpkg / 装好的 lib 加到 PATH/LIB
# build.rs 里指引 linker
println!("cargo:rustc-link-search=/path/to/lib");
println!("cargo:rustc-link-lib=xxx");
通用 Build / Dependency 报错
1. "本机能跑,CI 挂"
按出现频率 checklist:
- lockfile 没提交(
package-lock.json/poetry.lock/Cargo.lock/uv.lock)。 - 环境变量:本地
.env,CI 没设。 - 大小写:
User.tsimport 成./user,Mac/Win 过,Linux 挂。 - 行尾:CRLF/LF 混,
bash\r报command not found。
修复:.gitattributes加* text=auto eol=lf,git add --renormalize .。 - 时区:CI 是 UTC,本地不是。本地
TZ=UTC pytest试一遍。 - locale:
LANG=C跑一遍排查。 - 并行度:
pytest -n0/ 单线程跑一遍。 - 资源:CI 容器 2C4G,本地宽松,超时被压爆。
- 依赖跨平台二进制:
sharp、node-gyp、pyarrow、tensorflow需对应平台 wheel。
修复:pip install --only-binary=:all:强制 wheel,或在 CI 上装编译工具链。 - shell 差异:本地 zsh/fish,CI bash;
set -eo pipefail行为不同。
2. 循环依赖
- Python:
ImportError: cannot import name 'X' from partially initialized module - TS/Node:运行时 import 成
undefined,常表现为is not a function - Rust:crate 间编译期拒绝;模块内循环依赖通过 trait 抽象解耦
通用修复:抽出公共部分到第三个模块;或依赖倒置(高层定义 trait,低层实现)。
3. Dependency hell
Conflicting peer dependency: react@17 vs react@18
解法优先级
- 升级老依赖。
overrides/resolutions/[patch.crates-io]强制锁版本。- 最后才
--legacy-peer-deps/--force(把问题藏起来,迟早炸)。
预防
- 每个项目锁住主要依赖的 major 版本。
- 用 Renovate / Dependabot 持续小步升级,而不是几年一次大跳。
4. Docker 里能跑,Compose 里挂
最常见:服务名 vs localhost。
services:
app:
environment:
DB_HOST: db # ✅ 用服务名
# DB_HOST: localhost # ❌ localhost 是 app 容器自身
db:
image: postgres
服务启动顺序:depends_on 只保证启动顺序,不保证就绪。健康检查:
db:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 2s
retries: 30
app:
depends_on:
db:
condition: service_healthy
5. Apple Silicon 跨架构问题
rosetta 装的二进制是 x86_64,native 是 arm64,混用挂。
arch # 当前 shell 架构
uname -m # 系统架构
file $(which python) # 二进制是什么架构
经验
- 单一架构用到底,不要 native + rosetta 混。
- Docker 在 M 系列上:
docker run --platform linux/amd64 ...跑 x86 镜像(慢但能跑)。
如何贴报错给 AI
标准模板
我遇到这个报错:
<报错完整原文,包括 stack trace,不要省略也不要转述>
环境:
- 语言/版本:Python 3.11 / Node 20.10 / Rust 1.78 / TS 5.4
- 框架:FastAPI 0.110 / Next.js 14.2 / tokio 1.36 / Vite 5
- OS:Linux x86_64 / macOS arm64 / Windows 11
- 复现步骤:1. ... 2. ... 3. ...
我已经试过的:
- [尝试 1] → 结果
- [尝试 2] → 结果
相关代码(最小复现,< 30 行):
<贴>
请:
1. 一句话说明这个报错的根本含义。
2. 按概率列 3 个可能原因。
3. 每个原因给出验证命令/检查项,不要直接改我代码。
4. 等我反馈再给修复方案。
为什么这样写有效
- 报错原文 → AI 不必猜。
- 环境 → 排除版本差异(同一报错,Python 3.9 vs 3.12 修法可能不同)。
- 已试过的 → 避免无用建议反复出现。
- 要求先诊断后修复 → 避免 AI 看一眼就乱改。
反模式
❌ "我代码报错了,帮我看看" → 没有信息
❌ "怎么修这个 undefined 错误" → 一万种可能
❌ "直接帮我改代码" → AI 容易幻觉
❌ "刚才那个还是不行" → 还是不贴新报错
❌ 截图报错(图片识别会丢字符) → 用文本
一个 prompt 技巧:让 AI 先用人话复述
读完上面,先用 100 字以内告诉我:
1. 你理解的我现在的处境是什么?
2. 你打算怎么诊断?
等我确认你理解对了,再开始。
防止 AI 跑偏到错的方向上忙活半天。