mcpField
S
subgraph-doctor

subgraph-doctor

github.com/goldsky-ioData & databases124.0k installsUpdated today
Repository

About subgraph-doctor

subgraph-doctor is a skill for diagnosing and fixing existing Goldsky Subgraph failures. It guides users through CLI status checks, error logs, and GraphQL `_meta` data, while defining when issues should be escalated to support.

Key features

  1. 01Check Goldsky authentication and Subgraph status
  2. 02Diagnose with error logs and `_meta`
  3. 03Identify network, deployment, and mapping errors
  4. 04Resume, pause, or redeploy subgraphs
  5. 05Set boundaries for customer-facing troubleshooting

Use cases

  1. 01Investigate stalled or auto-paused indexing
  2. 02Find mapping errors that halt indexing
  3. 03Diagnose failed Subgraph deployments
  4. 04Check endpoints returning no data or 404

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/goldsky-io/goldsky-agent --skill subgraph-doctor

After installing, type/subgraph-doctorin Claude Code to confirm it loaded.

Bundled filesevals/trigger-eval.json

Details

From the project README

Subgraph Doctor

Diagnose and fix existing Goldsky Subgraph problems by running CLI commands, reading logs, identifying root causes, and executing fixes.

Boundaries

  • Diagnose and fix EXISTING subgraph problems.
  • Diagnose only subgraphs that are broken (failing, stalled, erroring, won't deploy). A healthy but slow subgraph is an optimization task — use /subgraph-builder (e.g. reducing/declaring eth_calls).
  • Do not build or scaffold new subgraphs — use /subgraph-builder for authoring/init/deploy.
  • Do not handle The Graph migrations — use /subgraph-migrate.
  • Do not serve as a command reference — use /subgraph-builder or goldsky subgraph <cmd> --help for CLI syntax and flag lookups.
  • Do not handle Turbo or Mirror pipelines — use /turbo-doctor or /mirror-doctor.
  • Customer-facing only. Use only goldsky CLI commands, the dashboard, and GraphQL queries. Never suggest graphman, kubectl, Datadog, or direct database access — those are internal Goldsky tooling. When a problem needs them, escalate to support (see Step 6).

Mode Detection

Before running anything, check if you have the Bash tool:

  • Bash available (CLI mode): Run commands directly and parse output.
  • Bash NOT available (reference mode): Give the user one command at a time, explain what to look for, and proceed based on what they paste back.

Diagnostic Workflow

Follow these steps in order. Each builds on the previous one.

Step 1: Verify Authentication

Run goldsky project list 2>&1 to confirm the user is logged in.

  • If logged in: Note the project name and continue.
  • If not logged in: Direct the user to /auth-setup. Do not proceed until auth works.
Step 2: Identify the Subgraph

Run goldsky subgraph list 2>&1 to list all subgraphs and their status.

If the user already named a subgraph (name/version), confirm it exists in the list. Otherwise show the list and ask which one to diagnose. Note its status and which network it indexes — a wrong network is one of the most common root causes (see Step 5).

Step 3: Triage by Symptom

Subgraph problems fall into a few families. Pick the path that matches the symptom:

SymptomLikely familyGo to
Deploy command failed (never created)Deploy-time errorStep 4 → "Deploy-time failures"
Stuck at a block / head not moving / stalled / auto-pausedIndexing stalledStep 4 → logs + _meta
Error / failed health, indexing haltedHandler/mapping errorStep 4 → logs
Stuck at low % during a migrationSync-from-scratch (slow), or handler errorStep 4 → logs + _meta
Endpoint 404 / no data / can't queryEndpoint or not-yet-syncedStep 4 → _meta + endpoint check
reached the subgraph limit, database unavailable, frozen with no log errorsOperational/quota (Goldsky-side)Step 6 (escalate)
Step 4: Gather Diagnostic Data

Run these and analyze before concluding:

# 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

Do not pull unfiltered logs. Subgraphs emit a huge volume at info/debug level — running goldsky subgraph log without --filter error is slow and extremely token-hungry, and rarely adds signal over the error-filtered view. If you genuinely need non-error context, scope it tightly: a very short window (--since 5m) and, if possible, grep for a specific string. Lead with errors + the _meta query below.

Then run the _meta query against the GraphQL endpoint — this is the single most useful check for "stuck" or "no data" subgraphs. It reports the latest indexed block:

{
  _meta {
    deployment
    hasIndexingErrors
    block { number hash timestamp }
  }
}
  • hasIndexingErrors: true → a handler/mapping error halted indexing. Go to the error patterns below.
  • block.number far behind the chain head → still syncing (or stalled). Compare against a block explorer.
  • block.number ahead of / not yet on the chain → wrong network deployed (see below).
Step 5: Match Error Patterns
Wrong network / contract on the wrong chain

Symptoms: Subgraph never produces data, or _meta shows a start/current block that doesn't exist yet on the target chain. Often the subgraph name hints at the intended chain.

Cause: The manifest's network/chain slug points at a different chain than intended, so the subgraph is waiting for blocks that haven't been mined.

Fix: Correct the network in subgraph.yaml (verify the exact chain slug against the supported-networks docs at docs.goldsky.com/chains/supported-networks — e.g. it's liteforge, not litvm-testnet) and redeploy a new version. Confirm the contract address actually exists on the target chain via a block explorer.

Deploy-time failures

The deploy command errors out and nothing gets created. Common cases:

Error / symptomCauseFix
no network <slug> foundWrong/unknown chain slug in subgraph.yamlUse the correct slug from supported networks.
YAML parse error from subgraph initIllegal characters in --contract-name (e.g. :, spaces from an explorer label)Pass a clean name: --contract-name PolymarketUMACTFAdapter.
subgraph must use a single apiVersion across its data sources. Found: 0.0.7, 0.0.9Mixed apiVersion across dataSources/templatesUnify apiVersion across the whole manifest.
Interface '<X>' not definedSchema references an undefined interfaceDefine the interface in schema.graphql.
Timeseries/aggregation spec errors (must have id field of type Int8, @unique missing, aggregations not supported in spec version 1.0.0)Schema uses timeseries/aggregations not valid for the spec versionFix the id type to Int8, add @unique, or remove aggregations.
A deployment with this name & version already existsRe-deploying the same name/versionBump the version, or goldsky subgraph delete <name/version> then redeploy.
Windows CLI install failsThe installer runs in WSL, not native WindowsUse auth-setup scripts/install.ps1. It installs the pinned CLI with npm inside WSL. Do not pipe a remote installer.
Handler / mapping errors (indexing halts)

Symptoms: hasIndexingErrors: true; logs show things like:

  • Mapping aborted at src/mappings/...: unexpected null in handler '<handler>' at block #<n>
  • Subgraph error ... code: SubgraphSyncingFailure
  • Token.load failures / Heap (out-of-memory) errors
  • WASM trap / "Handler skipped due to execution failure" (when nonFatalErrors is enabled)

Cause: A bug in the customer's AssemblyScript mappings — most often a null dereference. Classic case: an entity is never .save()d because the handler early-returns when a token's decimals()/symbol() reverts (non-ERC-20 contract), then a later handler .load()s that missing entity and panics.

Fix:

  1. Identify the handler and block from the error.
  2. Patch the mapping so it doesn't skip .save() on the null path (e.g. default decimals to a sentinel like 18, persist the entity, skip downstream pricing).
  3. Redeploy a new version and rewind to the first affected block so the missing entities re-initialize.
  4. As a stopgap to keep the endpoint serving (incomplete) data while you fix it, subgraphError: allow lets queries return partial results.

Goldsky-side caveat: a deterministic error with nonFatalErrors enabled may not auto-clear even after the underlying cause is resolved. If a subgraph stays errored after a correct redeploy, escalate (Step 6).

Stalled / auto-paused subgraph

Symptoms: Head stops advancing; Goldsky auto-pauses a stalled subgraph and emails you.

Cause: Often a handler error (above), sometimes a transient upstream RPC issue or a stale source chain.

Fix:

  1. Check logs and _meta for errors first.
  2. If it's a code bug, fix and redeploy. If it was transient, resume: goldsky subgraph start <name/version>.
  3. If the source chain itself is stale (no new blocks on the explorer either), there's nothing to index — wait for the chain.
Upstream RPC errors

Symptoms: eth_getLogs does not exist / method-not-supported, or Found no transaction for event / block-number mismatches.

Cause: The chain's RPC provider is misbehaving or missing methods — not the subgraph. (Real case: a node stamped every log with the request's fromBlock, so graph-node couldn't match logs to blocks and went fatal.)

Fix: This is Goldsky/RPC-side. Confirm it's not a manifest issue, then escalate (Step 6) with the exact error and block number.

Endpoint / query problems

Symptoms: 404 on the GraphQL endpoint, "no data", or rate-limit errors.

  • 404 / no data: The subgraph may not be synced yet (check _meta), or the public endpoint is disabled. Verify the endpoint URL with goldsky subgraph list <name/version>. Don't assume an endpoint is live before the resource exists and has synced.
  • Public vs private: If queries fail auth, the endpoint may be private. Toggle with goldsky subgraph update <name/version> --public-endpoint enabled (see /subgraph-builder).
  • Rate limits: Default is ~50 requests / 10 seconds. Higher limits are sales/support-gated — escalate (Step 6); don't promise a specific new limit.
Step 6: Present Diagnosis
## 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>

When to escalate to [email protected] (don't burn cycles guessing):

  • Operational/quota issues not visible via CLI: reached the subgraph limit (especially if the count looks wrong), database unavailable, frozen head with no log errors.
  • Upstream RPC bugs (eth_getLogs does not exist, log/block mismatches).
  • A subgraph that stays errored after a verified-correct redeploy.

Give the user the exact info to send: subgraph name/version, project ID, the GraphQL endpoint, the error string, and the affected block number. Mention they can reference using the AI/MCP for priority handling.

Step 7: Execute Fix

Offer to run fixes, and confirm before anything destructive:

  • Resume a paused subgraph: goldsky subgraph start <name/version>
  • Pause for maintenance: goldsky subgraph pause <name/version>
  • Redeploy a fixed version: goldsky subgraph deploy <name/new-version> --path .
  • Redeploy with a rewind: goldsky subgraph deploy <name/version> --start-block <firstAffectedBlock>
  • Delete and recreate (last resort, reindexes from scratch — warn the user): goldsky subgraph delete <name/version> then redeploy.

After a fix, re-check goldsky subgraph list <name/version> and the _meta query to confirm the head is advancing again.

Common mapping-code root causes (catch before redeploy)

When indexing halted on a handler/mapping error, the underlying cause is almost always one of these AssemblyScript mistakes. Check the mapping for them before redeploying — and recommend the Subgraph Linter (static analysis) plus Matchstick tests so they never reach a deploy again (see /subgraph-builder → references/testing.md):

Root causeSymptom it producesFix
Unchecked Entity.load(id)! force-unwrapunexpected null in handler panic when the entity is missingUse get-or-create; never !-unwrap a load.
Early-return that skips .save() (often after a reverting decimals()/symbol() on a non-ERC-20)later .load() panics; Token.load/Heap errorsUse try_ calls, default the value, persist the entity, skip only downstream pricing.
Division without a zero guardmath abort / unexpected nullWrap in a safeDiv (return 0 when denominator is 0).
Stale .save() after a helper already mutated the entityoverwritten/clobbered fields, wrong data (not always a crash)Load once, mutate, save once; don't save a stale copy.
Per-event eth_call that reverts or is undeclaredslow indexing or unexpected nullMake it revert-safe (try_) and declare it (specVersion 1.2.0+).

These are the causes behind the reactive symptoms in Step 5's "Handler / mapping errors". Fixing the code and rewinding to the first affected block is the durable fix.

Important Rules

  • Always gather data (logs + _meta) before diagnosing. Never guess.
  • "The product is solid — most issues are customer-side." Check the obvious customer causes first (wrong network, mapping bug, schema/manifest error) before assuming a Goldsky-side problem.
  • Never recommend graphman/kubectl/Datadog/database access to a customer. Escalate instead.
  • Confirm before destructive commands (delete, reindex from scratch).
  • Redeploying creates a new immutable version. Use tags so the frontend URL doesn't change (see /subgraph-builder).

When Bash Is Not Available

Give one command at a time, explain what to look for, and proceed based on the user's pasted output. Always prefer running commands directly when Bash is available.

Related

  • /subgraph-builder — Build, author, and deploy subgraphs; schema/mapping/manifest authoring; endpoints, tags, webhooks
  • /subgraph-migrate — Migrate a subgraph from The Graph
  • /auth-setup — CLI installation and authentication
  • /datasets — Chain prefixes and supported-network slugs
  • /turbo-doctor, /mirror-doctor — Pipeline (not subgraph) diagnosis

Comments

Markdown supported