关于 subgraph-doctor
subgraph-doctor 是用于排查并修复现有 Goldsky Subgraph 故障的技能,面向遇到部署失败、索引停滞或查询异常的用户。它按 CLI 状态、错误日志和 GraphQL `_meta` 数据逐步定位问题,并界定需要升级给支持团队的情况。
主要功能
- 01检查 Goldsky 身份验证与 Subgraph 状态
- 02结合错误日志和 `_meta` 诊断故障
- 03识别网络、部署及映射错误
- 04执行恢复、暂停或重新部署
- 05规定 Goldsky 客户端工具的排查边界
适用场景
- 01排查索引停滞或自动暂停
- 02定位映射错误导致的索引中断
- 03诊断 Subgraph 部署失败
- 04检查端点无数据或返回 404
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ goldsky-io/ goldsky-agent --skill subgraph-doctor安装后在 Claude Code 中输入/subgraph-doctor确认已加载。
附带文件evals/trigger-eval.json
详细介绍
Subgraph Doctor
通过运行 CLI 命令、读取日志、查明根本原因并执行修复,诊断和修复现有 Goldsky Subgraph 问题。
范围
- 诊断并修复现有 Subgraph 问题。
- 仅诊断已损坏的 Subgraph(失败、停滞、出错或无法部署)。运行缓慢但健康的 Subgraph 属于优化任务——请使用
/subgraph-builder(例如,减少或声明 eth_calls)。 - 不要构建或搭建新的 Subgraph——编写、
init或deploy请使用/subgraph-builder。 - 不要处理 The Graph 迁移——请使用
/subgraph-migrate。 - 不要充当命令参考——CLI 语法和标志查询请使用
/subgraph-builder或goldsky subgraph <cmd> --help。 - 不要处理 Turbo 或 Mirror 管道——请使用
/turbo-doctor或/mirror-doctor。 - 仅限面向客户的工具。 仅使用
goldskyCLI 命令、控制面板和 GraphQL 查询。切勿建议使用graphman、kubectl、Datadog 或直接访问数据库——这些是 Goldsky 内部工具。如果问题需要使用这些工具,请升级至支持团队处理(参见步骤 6)。
模式检测
在运行任何操作之前,检查是否有 Bash 工具:
- Bash 可用(CLI 模式): 直接运行命令并解析输出。
- Bash 不可用(参考模式): 每次向用户提供一条命令,说明要关注什么,并根据用户粘贴回来的内容继续操作。
诊断工作流
按顺序执行以下步骤。每一步都基于前一步的结果。
步骤 1:验证身份验证
运行 goldsky project list 2>&1,确认用户已登录。
- 如果已登录: 记下项目名称并继续。
- 如果未登录: 引导用户使用
/auth-setup。身份验证正常前不要继续。
步骤 2:识别 Subgraph
运行 goldsky subgraph list 2>&1,列出所有 Subgraph 及其状态。
如果用户已提供 Subgraph 名称(name/version),请确认它存在于列表中。否则,显示列表并询问要诊断哪个 Subgraph。记下其状态以及它索引的网络——网络错误是最常见的根本原因之一(参见步骤 5)。
步骤 3:根据症状分类
Subgraph 问题大致分为几类。选择符合症状的路径:
| 症状 | 可能类别 | 前往 |
|---|---|---|
| 部署命令失败(从未创建) | 部署时错误 | 步骤 4 →“部署失败” |
| 卡在某个区块 / head 未移动 / 停滞 / 自动暂停 | 索引停滞 | 步骤 4 → 日志 + _meta |
健康状态为 Error / failed,索引已停止 | Handler/mapping 错误 | 步骤 4 → 日志 |
| 迁移期间卡在较低进度百分比 | 从头同步(较慢)或 Handler 错误 | 步骤 4 → 日志 + _meta |
| 端点返回 404 / 没有数据 / 无法查询 | 端点问题或尚未同步 | 步骤 4 → _meta + 端点检查 |
reached the subgraph limit、database unavailable、无日志错误但冻结 | 运行状态/配额问题(Goldsky 侧) | 步骤 6(升级处理) |
步骤 4:收集诊断数据
运行以下操作,并在得出结论前分析结果:
# Errors only — START HERE. Widen the window (e.g. --since 24h) if nothing shows.
goldsky subgraph log <name/version> --since 1h --filter error 2>&1
# Subgraph + tag + deployment status
goldsky subgraph list <name/version> 2>&1
不要提取未经筛选的日志。 Subgraph 在
info/debug级别会产生大量日志——运行不带--filter error的goldsky subgraph log速度很慢且极其消耗令牌,与经过错误筛选的视图相比,通常也很少提供额外信息。如果确实需要非错误上下文,请严格限制范围:使用非常短的时间窗口(--since 5m),并尽可能按特定字符串 grep。优先查看错误和下面的_meta查询。
然后对 GraphQL 端点运行 _meta 查询——这是检查“停滞”或“没有数据”的 Subgraph 最有用的方法。它会报告最新的索引区块:
{
_meta {
deployment
hasIndexingErrors
block { number hash timestamp }
}
}
hasIndexingErrors: true→ Handler/mapping 错误导致索引停止。请查看下方的错误模式。block.number远落后于链的 head → 仍在同步(或已停滞)。请与区块浏览器进行比较。block.number超前于链上区块,或链上尚无该区块 → 部署的网络错误(见下文)。
步骤 5:匹配错误模式
网络错误/合约位于错误的链上
症状: Subgraph 始终无法生成数据,或者 _meta 显示的起始区块/当前区块在目标链上尚不存在。Subgraph 名称通常能透露预期的链。
原因: 清单中的 network/链标识指向了非预期的链,因此 subgraph 一直在等待尚未挖出的区块。
解决方法: 更正 subgraph.yaml 中的 network(请根据 docs.goldsky.com/chains/supported-networks 中的支持网络文档确认准确的链标识,例如应为 liteforge,而不是 litvm-testnet),然后重新部署一个新版本。通过区块浏览器确认目标链上确实存在该合约地址。
部署时失败
部署命令报错,且没有创建任何内容。常见情况如下:
| 错误/症状 | 原因 | 解决方法 |
|---|---|---|
no network <slug> found | subgraph.yaml 中的链标识错误或未知 | 使用支持网络列表中的正确标识。 |
subgraph init 出现 YAML 解析错误 | --contract-name 中包含非法字符(例如 :,或从区块浏览器标签中带入的空格) | 使用简洁的名称:--contract-name PolymarketUMACTFAdapter。 |
subgraph must use a single apiVersion across its data sources. Found: 0.0.7, 0.0.9 | dataSources/templates 中的 apiVersion 不一致 | 统一整个清单中的 apiVersion。 |
Interface '<X>' not defined | 架构引用了未定义的接口 | 在 schema.graphql 中定义该接口。 |
时序/聚合规范错误(must have id field of type Int8、缺少 @unique、aggregations not supported in spec version 1.0.0) | 架构使用的时序/聚合功能与规范版本不兼容 | 将 id 类型改为 Int8、添加 @unique,或移除聚合。 |
A deployment with this name & version already exists | 正在重新部署相同的 name/version | 升级版本,或先执行 goldsky subgraph delete <name/version>,然后重新部署。 |
| Windows CLI 安装失败 | 安装程序在 WSL 中运行,而非原生 Windows 环境 | 使用 auth-setup scripts/install.ps1。它会在 WSL 中通过 npm 安装固定版本的 CLI。不要通过管道运行远程安装程序。 |
处理程序/映射错误(索引中止)
症状: hasIndexingErrors: true;日志中显示类似以下内容:
Mapping aborted at src/mappings/...: unexpected null in handler '<handler>' at block #<n>Subgraph error ... code: SubgraphSyncingFailureToken.load失败/Heap(内存不足)错误- WASM 异常/“Handler skipped due to execution failure”(启用
nonFatalErrors时)
原因: 客户的 AssemblyScript 映射中存在错误,最常见的是空值解引用。典型情况:由于某个 Token 的 decimals()/symbol() 调用发生回滚(合约并非 ERC-20),处理程序提前返回,导致实体从未执行 .save();后续处理程序对缺失的实体执行 .load(),进而触发崩溃。
解决方法:
- 根据错误定位处理程序和区块。
- 修补映射,确保空值路径不会跳过
.save()(例如,将decimals默认设为18这类哨兵值,持久化实体,并跳过下游定价)。 - 重新部署一个新版本,并回退到首个受影响的区块,以便重新初始化缺失的实体。
- 作为临时措施,在修复期间保持端点继续提供(不完整的)数据,可使用
subgraphError: allow让查询返回部分结果。
Goldsky 端注意事项:启用
nonFatalErrors时,即使根本原因已解决,确定性错误也可能不会自动清除。如果 subgraph 在正确重新部署后仍处于错误状态,请升级处理(步骤 6)。
停滞/自动暂停的子图
**症状:**区块高度停止推进;Goldsky 自动暂停停滞的子图并向你发送邮件。
**原因:**通常是处理程序错误(见上文),有时是上游 RPC 暂时出现问题,或源链已过时。
修复方法:
- 首先检查日志和
_meta中是否有错误。 - 如果是代码问题,修复后重新部署。如果只是暂时性问题,则恢复运行:
goldsky subgraph start <name/version>。 - 如果源链本身已过时(区块浏览器上也没有新区块),就没有可供索引的内容——请等待链恢复。
上游 RPC 错误
症状:eth_getLogs does not exist/不支持该方法,或 Found no transaction for event/区块编号不匹配。
**原因:**链的 RPC 提供方出现异常或缺少相关方法——问题不在子图。(真实案例:某个节点将每条日志的区块号都标记为请求中的 fromBlock,导致 graph-node 无法将日志与区块匹配,最终进入致命错误状态。)
**修复方法:**这是 Goldsky/RPC 端的问题。确认不是清单问题后,提供确切错误信息和区块编号,升级处理(第 6 步)。
端点/查询问题
**症状:**GraphQL 端点返回 404、“没有数据”或触发速率限制错误。
- **404/没有数据:**子图可能尚未完成同步(检查
_meta),或公共端点已禁用。使用goldsky subgraph list <name/version>核实端点 URL。资源创建并完成同步之前,不要假设端点已可用。 - **公共与私有:**如果查询因身份验证失败,端点可能是私有的。使用
goldsky subgraph update <name/version> --public-endpoint enabled切换(参见/subgraph-builder)。 - **速率限制:**默认约为每 10 秒 50 个请求。更高的限制需要销售/支持团队批准——请升级处理(第 6 步);不要承诺具体的新限制。
第 6 步:说明诊断结果
## Diagnosis
**Subgraph:** <name/version>
**Network:** <chain>
**Symptom:** <one-line>
**Root cause:**
<what's wrong and why>
**Evidence:**
- <log line / _meta block number / error string>
**Recommended fix:**
1. <step>
2. <step>
**Prevention:**
<how to avoid it next time, if applicable>
需要联系 [email protected] 升级处理的情况(不要浪费时间猜测):
- 通过 CLI 无法查看的运行或配额问题:
reached the subgraph limit(尤其是计数看起来不正确时)、database unavailable、区块高度冻结且日志中没有错误。 - 上游 RPC 错误(
eth_getLogs does not exist、日志/区块不匹配)。 - 已确认重新部署的版本正确,但子图仍处于错误状态。
告知用户需要提供的确切信息:子图 name/version、项目 ID、GraphQL 端点、错误字符串和受影响的区块编号。提及他们可以说明是通过 AI/MCP 联系,以便获得优先处理。
第 7 步:执行修复
提出代为执行修复,并在执行任何破坏性操作前征求确认:
- 恢复已暂停的子图:
goldsky subgraph start <name/version> - 暂停以进行维护:
goldsky subgraph pause <name/version> - 重新部署修复后的版本:
goldsky subgraph deploy <name/new-version> --path . - 回退后重新部署:
goldsky subgraph deploy <name/version> --start-block <firstAffectedBlock> - 删除并重新创建(最后的手段,会从头重新索引——请提醒用户):
goldsky subgraph delete <name/version>,然后重新部署。
修复后,再次检查 goldsky subgraph list <name/version> 和 _meta 查询,确认区块高度已恢复推进。
映射代码的常见根本原因(重新部署前排查)
当索引因处理程序/映射错误而停止时,根本原因几乎总是以下 AssemblyScript 错误之一。重新部署前,请检查映射中是否存在这些问题,并建议使用 Subgraph Linter(静态分析)以及 Matchstick 测试,避免问题再次进入部署(参见 /subgraph-builder → references/testing.md):
| 根本原因 | 引发的症状 | 修复方法 |
|---|---|---|
未检查的 Entity.load(id)! 强制解包 | 实体缺失时,处理程序发生 unexpected null in handler 崩溃 | 使用获取或创建;切勿对 load 使用 ! 解包。 |
提前返回,跳过了 .save()(通常是在非 ERC-20 代币上调用 decimals()/symbol() 并发生回退后) | 后续 .load() 崩溃;出现 Token.load/Heap 错误 | 使用 try_ 调用,为值设置默认值,持久化实体,仅跳过后续定价。 |
| 除法未检查除数是否为零 | 数学运算中止 / unexpected null | 用 safeDiv 包装(除数为 0 时返回 0)。 |
辅助函数已修改实体后,又对过时副本调用 .save() | 字段被覆盖/冲掉、数据错误(不一定会崩溃) | 只加载一次,修改后只保存一次;不要保存过时副本。 |
每个事件都会执行可能回退或未声明的 eth_call | 索引缓慢或出现 unexpected null | 确保调用可安全处理回退(使用 try_),并进行声明(specVersion 1.2.0+)。 |
这些是第 5 步“处理程序 / 映射错误”中各类应急症状背后的原因。修复代码并回滚到第一个受影响的区块,才是持久的解决方法。
重要规则
- 诊断前始终收集数据(日志 +
_meta)。切勿猜测。 - “产品很可靠——大多数问题都出在客户一侧。”先检查明显的客户原因(网络错误、映射错误、schema/manifest 错误),再假设问题出在 Goldsky 一侧。
- 切勿建议客户使用
graphman/kubectl/Datadog/数据库访问。应升级处理。 - 执行破坏性命令(删除、从头重新索引)前,先确认。
- 重新部署会创建一个新的不可变版本。请使用标签,以免前端 URL 发生变化(参见
/subgraph-builder)。
Bash 不可用时
每次提供一条命令,说明要查看什么,并根据用户粘贴的输出继续操作。Bash 可用时,始终优先直接运行命令。
相关内容
/subgraph-builder— 构建、编写和部署子图;编写 schema/mapping/manifest;端点、标签、webhook/subgraph-migrate— 从 The Graph 迁移子图/auth-setup— CLI 安装与身份验证/datasets— 链前缀和受支持网络的 slug/turbo-doctor、/mirror-doctor— Pipeline(非子图)诊断