mcpField
S
subgraph-doctor

subgraph-doctor

github.com/goldsky-io数据与数据库124.0k 次安装今天更新
代码仓库

关于 subgraph-doctor

subgraph-doctor 是用于排查并修复现有 Goldsky Subgraph 故障的技能,面向遇到部署失败、索引停滞或查询异常的用户。它按 CLI 状态、错误日志和 GraphQL `_meta` 数据逐步定位问题,并界定需要升级给支持团队的情况。

主要功能

  1. 01检查 Goldsky 身份验证与 Subgraph 状态
  2. 02结合错误日志和 `_meta` 诊断故障
  3. 03识别网络、部署及映射错误
  4. 04执行恢复、暂停或重新部署
  5. 05规定 Goldsky 客户端工具的排查边界

适用场景

  1. 01排查索引停滞或自动暂停
  2. 02定位映射错误导致的索引中断
  3. 03诊断 Subgraph 部署失败
  4. 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。
  • 仅限面向客户的工具。 仅使用 goldsky CLI 命令、控制面板和 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> foundsubgraph.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.9dataSources/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: SubgraphSyncingFailure
  • Token.load 失败/Heap(内存不足)错误
  • WASM 异常/“Handler skipped due to execution failure”(启用 nonFatalErrors 时)

原因: 客户的 AssemblyScript 映射中存在错误,最常见的是空值解引用。典型情况:由于某个 Token 的 decimals()/symbol() 调用发生回滚(合约并非 ERC-20),处理程序提前返回,导致实体从未执行 .save();后续处理程序对缺失的实体执行 .load(),进而触发崩溃。

解决方法:

  1. 根据错误定位处理程序和区块。
  2. 修补映射,确保空值路径不会跳过 .save()(例如,将 decimals 默认设为 18 这类哨兵值,持久化实体,并跳过下游定价)。
  3. 重新部署一个新版本,并回退到首个受影响的区块,以便重新初始化缺失的实体。
  4. 作为临时措施,在修复期间保持端点继续提供(不完整的)数据,可使用 subgraphError: allow 让查询返回部分结果。

Goldsky 端注意事项:启用 nonFatalErrors 时,即使根本原因已解决,确定性错误也可能不会自动清除。如果 subgraph 在正确重新部署后仍处于错误状态,请升级处理(步骤 6)。

停滞/自动暂停的子图

**症状:**区块高度停止推进;Goldsky 自动暂停停滞的子图并向你发送邮件。

**原因:**通常是处理程序错误(见上文),有时是上游 RPC 暂时出现问题,或源链已过时。

修复方法:

  1. 首先检查日志和 _meta 中是否有错误。
  2. 如果是代码问题,修复后重新部署。如果只是暂时性问题,则恢复运行:goldsky subgraph start <name/version>。
  3. 如果源链本身已过时(区块浏览器上也没有新区块),就没有可供索引的内容——请等待链恢复。
上游 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(非子图)诊断

评论

支持 Markdown