踩坑速查
过去半年踩过的所有坑按主题分类。新人过一遍能省一周排错时间。每一条都对应一次真实事故。
红 = 致命陷阱(数据丢 / 假成功 / 永封)
黄 = 易翻车(构建失败 / 配置遗漏)
蓝 = 概念坑(容易理解错)
绿 = 经验法则(最佳实践)
① 部署 / Vercel / Fly.io
Fly worker 必须
cd worker 再 deployfly deploy -c worker/fly.toml 不会改 build context root;仓库根有 node_modules 和 .next,context 会炸到 1.9GB。解法:cd worker && fly deploy。Vercel 环境变量末尾可能带
\n 导致 Bearer 401worker → Vercel 鉴权 401 时,先
vercel env pull 检查末尾换行,删旧值重粘贴。Vercel Preview env 独立于 Production,模块级读取导致全 PR 红
LLM client 必须 lazy-init;PR Preview 全红先查模块顶层 env 读取 + Preview 环境变量是否缺失。
Vercel deployment protection 让 curl 验证失效
所有路径都 401 时,改用
vercel inspect <url> --logs grep ƒ /api/... 确认路由编译。推 main 自动部署,但推完 ≠ 已部署
必须
gh run list 看 CI success,再 curl 生产 URL 验证文件包含改动。Fly depot builder 挂时本地 venv fallback
deadline_exceeded 时 f2 fast path 可本地跑;必须从 DB 拉 cookie_data 注入;本地裸调抖音 200 空 body 需检查 cookie 有效性。
② 编码 / 类型安全 / 验证
next build 通过 ≠ 运行时安全Supabase
any 返回让字段名 / id 类型错误静默通过编译。改 API 前先跑 npm run test:all。new Date(null) 静默产生 1970 epoch渲染出"1月1日 08:00"是定位信号;formatter 必须
!d + isNaN 双重守卫。Worker HTTP 200 +
success:false 是陷阱只判
res.ok 会把抖音发送失败当成功;必须同时检查 data.success。API 契约漂移需双侧同步验证
前端改 payload 必须同时打开 worker 对照字段名;camelCase / snake_case / 缺字段只有两侧都看才能发现。
Next.js 16
revalidateTag 签名变更必须
revalidateTag(tag, "max") 两参数,单参数 tsc 报错。Server Component 里禁用
next/dynamic ssr:falseSC 内直接 import 即可;
dynamic + ssr:false 只能在 Client Component 里用。PostgREST embed 多 FK 必须显式 hint
加完 FK 立刻 grep 该表所有 embed 加
!fk_name;症状是 badge 有数但列表空。PostgREST
!inner embed 返回数组即使是多对一 FKTypeScript 类型推断为 Array,取值须
Array.isArray(c.x) ? c.x[0] : c.x 防御。Python from-import 绑定不受 monkeypatch 影响
须对每个 from-import 调用方模块单独
setattr,conftest 单点 patch 不够。嵌套函数双重 hook 陷阱
内层
except + return [] 让外层误判成功并覆盖 failure;内外层只允许一层记录同一信号。③ Schema / 数据库
migration 编号必须在写计划时就
ls 确认并行功能可能占用同一编号;文件名与文件内注释必须一致,否则线上撞号。
messages.status CHECK 约束容易写错只允许
pending_approval(不是 pending);message_queue 没有 content 字段,先写 messages 再关联。conversations INSERT 必须写 douyin_user_id漏传则 DM 永远发不出去,无报错静默标 failed;三字段缺一不可。
schema 有列 ≠ 有写入路径
FK 列全仓 grep
\\s*[:=] 若只命中 select 就是漏洞;2026-04-23 因此找出 messaging_account_id 定义多年从未被赋值。Supabase Management API SQL 单引号转义
curl -d 含单引号须用 $'...\\'...' 形式,否则 shell 截断 JSON。缺 API 时优先造 API,不要记手动 SQL playbook
补 API 封装业务逻辑,旧 SQL playbook 升级为"异常兜底";典型案例:accounts 删除(DELETE
/api/accounts/[id] 调 delete_account_safe RPC,2026-04-27 上线)。supabase-js 多语句事务标准解法
SECURITY DEFINER 函数 + RPC:BEGIN/COMMIT 用 Postgres 函数封装,
supabase.rpc() 调;RETURN JSONB 传业务错误码。supabase-py
nullsfirst=False 不会真的生成 NULLS LASTDESC 默认 NULLS FIRST,全部 NULL 行飘顶;必须显式
.not_.is_('col', 'null') 过滤;leads.ts 同坑。python | tail -25 阻塞 stdout,监控文件永远 0 字节用
python -u | tee;或等脚本结束再读;或直接查 DB 计数绕开 stdout 监控。④ 多租户 / RLS
三层防御分工
RLS 只做 org 隔离 / API guard 做角色差异 / UI 置灰是第三层;RLS 里不 JOIN role 表。
预埋
org_id 列不等于数据正确关联落地 RLS 前必须 SELECT 审计各表
org_id 分布,发现孤立 org 先清理再收紧政策。多租户收紧时必须全仓巡查
[id] DELETE/PATCH 路由V1 单租户 handler 常把 auth 下沉 middleware;多租户下任何登录用户猜 UUID 即可删他 org 的行 — 知识库 DELETE 就这样裸奔过。
⑤ LLM / Prompt
中文 system prompt 内层引号用「」不用 ASCII 双引号
外层 JS 字符串 + 内层 ASCII
" 会截断字符串,build 才报错;默认用「」或 Unicode 弯引号。LLM 负向规则堆砌导致机器味
"绝不/严禁"规则 >6 条让模型进 careful mode;修法:充实 PERSONA 素材 + few-shot 示范替代规则。
few-shot 场景必须与实际调用场景严格一致
冷开场(无 user 先发言)vs 暖场回复是两套逻辑,写 few-shot 前先确认谁先说话。
LLM 上下文用自然语言而非 KV 格式
KV 格式让模型进"档案查询"模式;改自然语言句子输出更自然。
DeepSeek V3 tool_call 协议字符泄漏到 content
content 里出现
function<|tool▁sep|>NAME,需 extractLeakedToolCalls 清洗;Qwen3 无此问题;2026-04-27 OpenRouter 多语言幻觉事件后分析路径全切 Qwen3。LLM 结构化 JSON 输出 6 层防御
token 预算 / batch 上限 / 强制 1:1 / 多级 parser / raw 日志 / 模型选择 / cron 频率设计 —— 缺一就丢数。
LLM 重写 DM 文案的两类质量陷阱
方括号表情代码
[勾引] 漏出 + 杜撰具体地址(成华区展厅);prompt 层禁令 + strip_bracket_emojis 后处理兜底。⑥ Playwright / 抖音抓取
Playwright session 必须持久化 profile
用
launch_persistent_context + user_data_dir;别随手 close 丢 cookie;手机 app ≠ PC web session。Playwright
networkidle 在 Supabase 实时页面超时改用
domcontentloaded + wait_for_timeout(2000~3000),Realtime WS 保活导致 networkidle 永不触发。Playwright MCP
browser_run_code 可获取 HttpOnly cookiesdocument.cookie 拿不到 HttpOnly 字段;必须用 browser_run_code 调 page.context().cookies()。本地 Playwright MCP 是抖音 cookie 续期标准路径
Fly.io IP 被封,本地 Mac Playwright MCP 扫码不受限,是零成本续期方案(约每 15-30 天一次)。
QR 图片必须跟随平台轮换周期持续刷新
扫码登录只截一次 QR 是定时炸弹;抖音 60s 轮换,前端必须每 poll 覆盖新图。
worker 同步调用不适合 VPN 不稳定环境
/scrape/source/{id} 单条耗时 1-2 分钟,VPN 抖动必超时;批量触发走 cron/scrape 异步入队。Fly Tokyo IP 抖音用户查找路径全封
handle / 搜索 / profile API 全返回空或报错;
v.douyin.com 302 跳转不受封锁是唯一绕过。⑦ 抖音 DM 风控
陌生人 DM 是 1 条/对/方向 永久配额
同一 sec_uid 招呼信息只能发 1 条 — 对方没回复 / 没互关之前再发都返 7462。规模触达只能扩号,单号扩不动。
cmd:100 OK ≠ 真投递
必须
blackboxprotobuf 解 body.100.6 JSON 校验 status_code==0;7911=速率软封约 24h;22102+tip 空=账号观察期 24-72h 完全停止。send-loop 探针 cold-start 无效设计
fetch_probe_target 选 sent_at 最新 = 刚发未回复必 7462;正确选法:role=user 入站会话;0 条入站时用 --skip-probe fallback。抖音 DM 发送必须先暖场再跳 profile
cold context 直跳 profile 触发 CAPTCHA;必须先访问首页 feed 再跳目标页。
"养关系"暖场序列必须走 Playwright,禁止 HTTP 直签
行为信号缺失 = 扣分大头;HTTP 直签互动行为会被行为序列模型识别;遇到"为省事 HTTP 直签互动"提案立刻拦截。
抖音验证码中间页 vs 账号封号区分
captcha_markers / ban_keywords 双列表;验证码只 mark_failure 不 ban。
抖音 Draft.js 输入框中
\n 直接触发 Enter=发送page.keyboard.type 多段文案会在第 1 个 \n 处提前发送并消耗永久配额;必须 Shift+Enter 换行或合并段。WDA
send_keys 多行文案被切成多条 DMiOS App DM 输入框 Enter=Send;6 行被切 6 条,第 1 条吃配额、后 5 条吃风险分;解法 A 文案单行 + 解法 B sender collapse
\n 兜底。⑧ 网络 / VPN
macOS VPN TUN 环境下网络连接绕过
pip 用 NO_PROXY="*";curl/API 用 --resolve + 现场 nslookup 取 IP(IP 会轮换);DNS 正常但 TCP 超时即 TUN 问题。VPN 完全瞬断(instant reject)时不要继续试绕过
0-3ms connect failed 是路由 flap,
--resolve / NO_PROXY 均无效;直接 ScheduleWakeup 270s 等路由恢复。macOS 磁盘满时 Bash 全面哑掉
ENOSPC 任何命令都静默失败;先让用户
rm ~/.claude/projects/*/task-outputs/*,不要反复试 Bash。fal.ai 免费账户 GCS 403 必须用 base64 绕过
fal_client.encode_image() 转 base64 传图,不要直接传文件路径。⑨ Git / 协作流程
开始编辑前必须确认 local 与 remote 同步
截图 UI 与 local 代码不一致时优先怀疑 local 落后远端,先
git pull 再动手。cherry-pick -x 是 WIP 分支隔离单 commit 上 main 的干净做法WIP 不能整体合并时从
origin/main 新建分支 cherry-pick -x 再快进 push。并行 agent 活跃期 feature branch 会被静默切走
感知到并行活动立刻放弃 branch 直推 main,branch 在并行期比直推更危险。
写 UI 操作指南前必须 grep 验证当前状态
凭 memory / spec 写指南必错;UI 会变而记忆不会自动更新。
spec 里"保留兼容 N 周"的代码必须主动清理
不主动回来删就永远是 dead code,新人 / curl / 旧脚本仍会误触。
接 CI 前先把
scripts/** 加入 eslint ignore一次性调试脚本默认堆
any;首次 lint CI 必踩;统一 ignore 不要 disable 满地撒。⑩ 产品 / UX
DB 实体不能让用户手动输入内部 ID
号源 / 账号 / 知识库等实体必须列表展示,绝不要求输入 sec_uid / UUID。
Lark 卡片风格偏好:简洁、优美、图表优先
≤300 字;
column_set 做双列对比和 KPI 矩阵;严禁 ASCII 图 / Markdown 表;先问"像不像上线海报"。Akke 用 Lark 不是飞书
国际版
larksuite.com;措辞一律写 "Lark",用户对这个区分敏感。私信对话页只显示真实已投递 DM
sent_at IS NOT NULL 是规范过滤条件;草稿只属于消息审核流。
想看完整列表?项目 docs/claude-memory/MEMORY.md 有 100+ 条按主题归类的记忆,每一条都对应一次真实事故 + 修法。本页是精选版。