关于 prisma-next-debug
用于调试 Prisma Next 的技能,说明如何解析 CLI、运行时和 SQL 错误结构,并根据错误信息找到相应处理路径,面向开发者和 Agent。
主要功能
- 01区分 CLI、运行时与 SQL 错误格式
- 02根据代码、严重性和元数据分流
- 03通过 meta.code 处理包装错误
- 04将常见症状对应到后续步骤
适用场景
- 01诊断 Prisma Next CLI 故障
- 02排查查询运行时错误
- 03处理迁移与 Schema 问题
- 04解读原始 SQL 驱动错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ prisma/ prisma-next --skill prisma-next-debug安装后在 Claude Code 中输入/prisma-next-debug确认已加载。
详细介绍
Prisma Next — 调试
编辑数据契约。其余交给 Prisma 处理。
Prisma Next 调用失败时,框架会返回一个结构化信封。Agent 的任务是读取信封、根据 code 路由,并转到相应的编写技能来实际修复问题。本技能介绍信封的形状和路由方式,不会重复相邻技能的工作流。
适用场景
- 用户粘贴了错误信封(CLI 失败、运行时异常、
--json输出)。 - 用户说 “我的查询无法通过类型检查”、“我的迁移无法应用”、“我的 emit 失败了”、“运行时崩溃了”。
- 用户提到了稳定代码(
PN-CLI-*、PN-MIG-*、PN-RUN-*、PN-SCHEMA-*、MIGRATION.*、CONTRACT.*、LINT.*、BUDGET.*、PLAN.*、RUNTIME.*)。 - 用户提到了:Studio、EXPLAIN、查询日志、预处理语句、漂移、哈希不匹配、能力、规划器。
不适用场景
- 用户想编写查询 / 模型 / 迁移 → 使用相应的编写技能。
- 用户想预防错误(lint、预算、类型级保护)→ 使用
prisma-next-runtime。 - 用户希望修改框架,因为问题出在框架本身(没有可用于路由的信封、确实缺少某项能力)→ 使用
prisma-next-feedback。
核心概念
两种信封形状
Prisma Next 会根据抛出错误的位置生成两种不同的信封。路由之前,先确认你拿到的是哪一种。
1. CLI 信封 — 由 prisma-next ... 命令生成(emit、db init/update/verify/sign/schema、migration plan/apply/show/status、init)。形状如下(参见 packages/1-framework/1-core/errors/src/control.ts 中的 CliErrorEnvelope):
{
"ok": false,
"code": "PN-MIG-2001",
"domain": "MIG",
"severity": "error",
"summary": "Unfilled migration placeholder",
"why": "...",
"fix": "...",
"where": { "path": "...", "line": 42 },
"meta": { "slot": "..." },
"docsUrl": "https://prisma-next.dev/..."
}
完整代码格式为 PN-<domain>-<NNNN>。使用中的 domain 有:CLI、MIG、RUN、CON、SCHEMA。严重性为 error | warn | info — migration status 的诊断结果为 warn 时会以 0 退出,因此应根据严重性和代码共同判断,而不能只看退出代码。
2. 运行时信封 — 执行查询时由进程内运行时抛出(参见 packages/1-framework/1-core/framework-components/src/execution/runtime-error.ts 中的 RuntimeErrorEnvelope):
{ name: 'RuntimeError', code: 'BUDGET.TIME_EXCEEDED', category: 'BUDGET', severity: 'error', message: '...', details: { ... } }
category 的取值为 PLAN | CONTRACT | LINT | BUDGET | RUNTIME(即 code 的前缀)。details 保存结构化上下文(details 相当于运行时信封中的 CLI 信封 meta 字段)。
3. SQL 驱动程序错误 — 显示为 SqlQueryError / SqlConnectionError(参见 packages/2-sql/1-core/errors/)。SqlQueryError 的字段:kind: 'sql_query'、sqlState(Postgres SQLSTATE,例如 '23505')、constraint、table、column、detail、cause。这些错误没有 PN-* 代码 — 应根据 sqlState 和约束元数据进行路由。SQL 驱动程序错误通常会在传递给用户之前由中间件包装,但原始 SQL 路径可能会直接显示这些错误。
包装错误与 meta.code
有些命令会将下游错误重新包装成 PN-RUN-3000(errorRuntime)信封,并将原始代码存入 meta.code。最重要的情况是:migrate 会通过 mapMigrationToolsError 包装 MigrationToolsError(其代码包括 MIGRATION.HASH_MISMATCH、MIGRATION.STALE_CONTRACT_BOOKENDS、MIGRATION.AMBIGUOUS_TARGET)。你看到的信封是 code: 'PN-RUN-3000',而 meta.code: 'MIGRATION.HASH_MISMATCH'。当 code 为 PN-RUN-3000 时,务必检查 meta.code — 路由所需的信息就在这里。
如何索取完整信封
如果用户只粘贴了人工可读的摘要,请索取 --json 输出(机器可读信封),或让用户使用 -v 重新运行(CLI 会打印完整的结构化字段)。--json 和 -v 是所有 CLI 命令通用的全局标志。
路由 — 脚本拆解与已关闭的客户端
这些症状不是 PN-* 信封格式——请根据消息文本进行路由,并转至 prisma-next-runtime § 作为脚本运行(拆解)。
| 症状 | 下一步 |
|---|---|
TypeError: db.end is not a function | 运行时客户端不提供 db.end()——那是 node-postgres 连接池 API(pool.end())。正确的调用是 await db.close()。请参阅 prisma-next-runtime § 作为脚本运行(拆解)。 |
| 查询结果已打印,但脚本仍然挂起/进程无法退出 | 在 Postgres 上,由 façade 管理的 pg.Pool 会使事件循环保持活动状态。请在脚本返回前调用 await db.close(),或在脚本模块顶部使用 await using db = postgres<Contract>(...)(不要在请求处理程序内使用 await using——其作用域仅限代码块,会在每个请求结束时关闭)。请参阅 prisma-next-runtime § 作为脚本运行(拆解)。 |
Error('Postgres client is closed') / Error('SQLite client is closed') / Error('Mongo client is closed') | 客户端已通过 db.close() 关闭(终止状态)。请移除提前调用的 close(),调整顺序以确保所有查询完成后最后调用 close(),或者在需要重新连接时构造新的 db。请参阅 prisma-next-runtime § 作为脚本运行(拆解)。 |
路由 — 症状和代码 → 下一步
唯一可信来源:读取信封,根据 code(对于包装后的错误,则根据 meta.code)查找对应行,并按照下一步操作。
| 代码 | 出现位置 | 后续操作 |
|---|---|---|
PN-CLI-4001 未找到配置文件 | 大多数 prisma-next 命令 | 运行 prisma-next init,或传入 --config <path>。 |
PN-CLI-4002 缺少契约配置 | contract emit、db * | 在 prisma-next.config.ts 中添加 contract: { ... }。参见 prisma-next-contract。 |
PN-CLI-4003 契约验证失败 | contract emit、db * | 修复 where.path 中指定的契约源后,重新运行 pnpm prisma-next contract emit。参见 prisma-next-contract。 |
PN-CLI-4005 必须提供数据库连接 | db *、migrate、migration status | 传入 --db <url>,或在 prisma-next.config.ts 中设置 db.connection。 |
PN-CLI-4011 配置中缺少扩展包 | contract emit(例如,契约使用了 pgvector.Vector(...),但配置未列出 pgvector 包) | 将 meta.missingExtensions 中指定的描述符添加到 prisma-next.config.ts 的 extensions 中。参见 prisma-next-contract。 |
PN-CLI-4020 迁移规划失败 | db init、db update | 检查 meta.conflicts。每种冲突的恢复方式各不相同——请参阅 prisma-next-migrations。 |
PN-CLI-5002/5003/5004/… 初始化错误 | prisma-next init | 根据 meta.missingFlags 或 meta.allowed 中列出的缺失/无效标志重新运行。 |
PN-MIG-2001 迁移占位符未填充 | node migrations/app/<dir>/migration.ts(自行生成)或 migrate | 编辑 migration.ts,将指定的 placeholder("<slot>") 替换为实际的查询闭包,然后自行生成。参见 prisma-next-migrations。 |
PN-MIG-2002 未找到 migration.ts | 读取迁移包时 | 从版本控制中恢复,或使用 migration plan 构建新的包。 |
PN-MIG-2003 默认导出无效 | 加载 migration.ts 时 | 使用 export default class extends Migration { ... }(或工厂函数 () => ({ ... }))。参见 prisma-next-migrations。 |
PN-MIG-2005 dataTransform 契约不匹配 | 构建数据转换查询计划时 | 将同一个 endContract 引用传给 dataTransform(endContract, …) 和查询构建器上下文。 |
PN-RUN-3001 数据库未签名 | db verify、运行时启动 | 数据库尚无标记。运行 prisma-next db init --db <url>(用于空基线数据库),或运行 db update --db <url>(直接应用契约)。 |
PN-RUN-3002 哈希不匹配 | db verify、运行时启动 | 标记与契约哈希不一致。可以向前迁移(migrate / db update),也可以在手动修复后确认数据库无误时运行 db sign。参见 prisma-next-migrations。 |
PN-RUN-3003 目标不匹配 | 运行时启动 | 契约目标 ≠ 配置目标;请使两者一致(参见 meta.expected / meta.actual)。 |
PN-RUN-3004 架构验证失败 | db verify(完整模式) | 检查 meta.verificationResult。运行 db update 进行协调,或调整契约。 |
PN-RUN-3010 架构验证失败(CLI 层) | db verify(仅检查架构) | 与 3004 相同。 |
PN-RUN-3020 迁移运行器失败 | migrate、db update、db init | 检查 meta 中的冲突;协调架构漂移后重新运行。已应用的迁移会保留。 |
PN-RUN-3030 破坏性更改需要确认 | db update(交互模式下会提示;非交互模式下会返回此代码) | 使用 -y(或 --yes)重新运行以应用更改,或使用 --dry-run 预览。只有 db update 有此流程——migrate 不会通过标志来限制破坏性操作。 |
PN-RUN-3000 (包装错误) | migrate 以及其他包装 MigrationToolsError 的命令 | 读取 meta.code。情况包括:MIGRATION.HASH_MISMATCH(重新生成:node migrations/app/<dir>/migration.ts);MIGRATION.AMBIGUOUS_TARGET(并发迁移——参见 prisma-next-migration-review);MIGRATION.STALE_CONTRACT_BOOKENDS(重新运行 migration plan);MIGRATION.NO_INVARIANT_PATH / MIGRATION.UNKNOWN_INVARIANT(参见 prisma-next-migration-review);MIGRATION.PATH_UNREACHABLE / MIGRATION.MARKER_MISMATCH(运行 migrate --show --db $URL 检查路径,然后运行 migration plan --from <from> --to <target> 或 migration list 审核图——参见 prisma-next-migration-review)。 |
PN-SCHEMA-0001 | db verify 架构检查 | 实际架构不符合契约。差异记录在 meta.verificationResult 中。运行 db update 或调整契约。 |
MIGRATION.UP_TO_DATE / .DATABASE_BEHIND | migration status 的 info 诊断 | 仅供参考;退出码为 0。参见 prisma-next-migration-review。 |
MIGRATION.MISSING_INVARIANTS | migration status 的 info 诊断 | 实际标记在结构上已到达目标哈希,但未包含目标引用所要求的全部不变量。运行 migrate --to <name> --db $URL,选择涵盖缺失不变量的路径。参见 prisma-next-migration-review。 |
MIGRATION.NO_MARKER / .MARKER_NOT_IN_HISTORY / .DIVERGED / CONTRACT.AHEAD / CONTRACT.UNREADABLE | migration status 的 warn 诊断(退出码为 0;CI 门禁会解析 --json) | 同时查看 severity 和 code。prisma-next-migration-review 涵盖菱形/分叉/标记不在历史记录中的处理流程。 |
BUDGET.ROWS_EXCEEDED / BUDGET.TIME_EXCEEDED | 启用了 budgets 中间件时的运行时 | 调整 budgets({ maxRows, maxLatencyMs, ... }),或重写查询。参见 prisma-next-runtime。 |
LINT.SELECT_STAR / LINT.NO_LIMIT / LINT.DELETE_WITHOUT_WHERE / LINT.UPDATE_WITHOUT_WHERE / LINT.READ_ONLY_MUTATION | 启用了 lints 中间件时的运行时 | 修复查询(添加 WHERE / LIMIT / 显式列),或放宽 lint 配置。参见 prisma-next-runtime。 |
PLAN.HASH_MISMATCH | 运行时执行预编译计划时 | 构建此计划所依据的契约与运行时契约不匹配。重新生成、重新构建并重新部署。 |
CONTRACT.MARKER_MISSING / CONTRACT.MARKER_MISMATCH | 运行时执行前进行标记检查时 | 与 PN-RUN-3001 / PN-RUN-3002 属于同一类错误,但由运行时在进程内抛出,而非由 CLI 抛出。恢复方式相同。 |
RUNTIME.ABORTED(details.phase = encode|decode|stream|beforeExecute|afterExecute|onRow) | 执行期间触发 AbortSignal 时的运行时 | 这是取消操作,不是错误;请将其传递给调用方。 |
SqlQueryError(无 PN- 代码) | 原始 SQL 路径中出现驱动程序错误时 | 检查 sqlState + constraint + table + column。Postgres 23505 = 唯一约束冲突,23503 = 外键约束冲突,等等。修复数据或架构。 |
提及某项能力的 TypeScript 错误(例如,类型上没有 returning(),或从多重加载中对多重关系使用 include) | 编写代码时,任何信封触发之前 | 能力门控在契约中声明(capabilities 块,按目标/系列命名空间划分),而非在 prisma-next.config.ts 中声明。能力声明请参阅 prisma-next-contract,关于哪些方法受哪些能力门控,请参阅 prisma-next-queries。启用后重新生成(pnpm prisma-next contract emit)。 |
提及 db.orm.<Model> 上缺少字段/方法或 Contract 形状过时的 TypeScript 错误 | 编写代码时 | 重新生成(pnpm prisma-next contract emit);确认 db.ts 使用 postgres<Contract, TypeMaps>(...) 实例化(类型参数会传递契约类型)。参见 prisma-next-runtime 和 prisma-next-contract。 |
如果信封中的 code 不在此表中,请严格按照信封的 fix 字段执行——这是框架的首选后续操作。如果 fix 为空或没有帮助,请通过 prisma-next-feedback 升级反馈。 |
常见陷阱
- 只读取
summary,不看信封的其他内容。code、severity、why、fix、meta/details,以及(对于 CLI 错误)where都至关重要。Agent 根据code路由;用户看到的是summary。 - 忽略
severity。migration status会输出 warn 级诊断信息,并且以 0 退出。如果 Agent 只检查退出代码,就会漏掉所有并发迁移警告。 - 在
PN-RUN-3000中跳过meta.code。 该信封只是一个包装器——真正的代码位于meta.code中。 - 把漂移当作可以用
db sign消除的问题。db sign会根据当前契约哈希写入标记,但首先必须通过架构验证。使用db sign前先运行db verify。 - 部分失败后未检查状态就重新运行
migrate。db schema --db <url>会显示实时结构;migration status --db <url> --json会显示标记的实际位置。
Prisma Next 目前尚不支持的功能
- Studio / GUI 数据库浏览器。 没有第一方 Studio。替代方案:使用
prisma-next db schema查看实时架构的 CLI 树状结构,或者通过DATABASE_URL使用第三方工具(TablePlus、DataGrip、psql)。如果需要内置 GUI,请通过prisma-next-feedback提交功能请求。 - 一流的查询日志记录中间件。 框架不附带内置的“记录每条查询”中间件。替代方案:编写一个包装每个操作的小型自定义中间件(有关中间件组合,请参阅
prisma-next-runtime)。如果需要内置查询日志,请通过prisma-next-feedback提交功能请求。 EXPLAIN集成。 执行计划没有一流的.explain()。替代方案:将 EXPLAIN 编写为原始查询(db.sql.raw\EXPLAIN ANALYZE ...`;请参阅prisma-next-queries)。如果需要一流的 EXPLAIN 功能,请通过prisma-next-feedback` 提交功能请求。- 面向用户的预处理语句缓存接口。 适配器会在底层为参数化查询准备语句,但你无法按名称预先准备并重新执行语句。替代方案:使用 TypedSQL(请参阅
prisma-next-queries)。如果需要一流的预处理语句 API,请通过prisma-next-feedback提交功能请求。
信封无法指明后续操作时如何寻求帮助
- 使用
-v(或使用--json获取机器可读输出)重新运行,以获取完整信封。 - 如果信封确实没有提供有用信息——
fix为空、缺少meta、summary内容笼统——这说明框架的支持能力存在缺口;请将信封、契约源(已清理敏感信息)和复现步骤提交至prisma-next-feedback。
检查清单
- 已识别信封类型(
CliErrorEnvelope、RuntimeErrorEnvelope、SqlQueryError)。 - 已阅读所有字段——
code、severity、why、fix、meta(或details),以及存在时的where。 - 如果
code为PN-RUN-3000,也已读取meta.code。 - 已根据
code路由到后续操作(若表格有说明,也已转到匹配的编写技能)。 - 已使用相关 CLI 命令(
db verify、migration status --json、contract emit、migrate)重新验证。 - 未臆造 Studio / EXPLAIN / 查询日志 API——已使用文档所述的替代方案,并将未满足的能力需求提交至
prisma-next-feedback。