fix-merkle-root-mismatch
Skill76 starsChanged 20 days agoApache-2.0View on GitHub
Use this skill AFTER running /investigate-merkle-root-mismatch to investigate the issue. Check if port 9090 is already in use: If not in use, start port-forward in background: Wait a few seconds, then verify it's working: IMPORTANT: User confirmation required before executing. Before making any changes to the relayer database, you MUST: Once confirmed, insert the correct merkle tree insertions via the relayer API: Request schema: Verify response: The API should return a success response with the count of inserted entries. IMPORTANT:…
- Sends data out
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 9 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 13
Use this skill AFTER running /investigate-merkle-root-mismatch to investigate the issue.
- Very specific: line 31
Investigation completed: - Run /investigate-merkle-root-mismatch first to identify mismatched entries
- Distinctive: line 45
Check if port 9090 is already in use:
- Distinctive: line 51
If not in use, start port-forward in background:
- Distinctive: line 57
Wait a few seconds, then verify it's working:
- Distinctive: line 67
Before making any changes to the relayer database, you MUST:
- Distinctive: line 76
Ask the user to get explicit confirmation:
- Distinctive: line 123
Ask the user to confirm:
- Distinctive: line 138
After the relayer restarts, verify the fix:
- Distinctive: line 241
API returns error: Check the error message, verify domain_id and message_id format
- Distinctive: line 242
Relayer restart fails: Check kubectl access and pod status
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Fix Merkle Root Mismatch
When to Use
Use this skill AFTER running /investigate-merkle-root-mismatch to investigate the issue.
- User request triggers:
- "Fix the merkle root mismatch on [chain]"
- "Apply the merkle tree fixes"
- "Update the relayer database with correct message IDs"
Input Parameters
| Parameter | Required | Default | Description |
origin | Yes | - | The origin chain to fix (e.g., polygonzkevm, ethereum) |
domain_id | Yes | - | Domain ID of the chain |
environment | No | mainnet3 | mainnet3 or testnet4 |
merkle_tree_insertions | Yes | - | List of corrections: [{leaf_index, message_id, block_number}] |
Prerequisites
- Investigation completed - Run
/investigate-merkle-root-mismatchfirst to identify mismatched entries kubectlaccess to the relayer pods- Port-forward already established to relayer (port 9090)
Fix Workflow
Step 0: Find Monorepo Root
MONOREPO_ROOT=$(git rev-parse --show-toplevel)Step 1: Verify Port-Forward is Active
Check if port 9090 is already in use:
lsof -i :9090If not in use, start port-forward in background:
kubectl port-forward omniscient-relayer-hyperlane-agent-relayer-0 9090:9090 -n [environment] &Wait a few seconds, then verify it's working:
curl -s "localhost:9090/merkle_tree_insertions?domain_id=[domain_id]&leaf_index_start=0&leaf_index_end=1"Step 2: Present Changes for Confirmation
IMPORTANT: User confirmation required before executing.
Before making any changes to the relayer database, you MUST:
Present a summary of ALL changes to be made in a clear table format:
Leaf Index Correct Message ID Block Number 1477 0x4bb3e20db45366a6a360ad2639c5421ea622a69b89b2edb045aa97e2051529b7 9891832 1478 0xa66dbdc1874acfddf14e75e6a20dd1632e9e3206c5f5855884da0d26d8ca12fa 9891872 - Ask the user to get explicit confirmation:
- Question: "Do you want to apply these merkle tree fixes to the relayer database?"
- Options: "Yes, apply fixes" / "No, cancel"
- Only proceed if the user explicitly confirms.
Step 3: Apply Merkle Tree Fixes
Once confirmed, insert the correct merkle tree insertions via the relayer API:
curl -X POST \
-H 'Content-type: application/json' \
'localhost:9090/merkle_tree_insertions' \
-d '{
"merkle_tree_insertions": [
{
"chain": [domain_id],
"insertion_block_number": [block_number],
"leaf_index": [index],
"message_id": "0x..."
}
]
}'Request schema:
{
"merkle_tree_insertions": [
{
"chain": "<domain_id as number>",
"insertion_block_number": "<block number as number>",
"leaf_index": "<leaf index as number>",
"message_id": "<0x-prefixed H256 hash>"
}
]
}Verify response: The API should return a success response with the count of inserted entries.
Step 4: Restart Relayer
IMPORTANT: User confirmation required before executing.
Ask the user to confirm:
- Question: "Do you want to restart the relayer to apply the database fixes?"
- Options: "Yes, restart relayer" / "No, I'll restart manually later"
Only proceed if the user explicitly confirms.
Once confirmed, restart the relayer to rebuild its in-memory merkle tree:
pnpm --dir typescript/infra exec tsx ./scripts/agents/restart-agents.ts -e [environment] --context hyperlane --role relayerStep 5: Validate Fix
After the relayer restarts, verify the fix:
5.1: Get Latest Index
Query Grafana for the current tree size:
Use mcp__grafana__query_prometheus with:
- datasourceUid: grafanacloud-prom
- expr: hyperlane_latest_tree_insertion_index{origin="[origin]", hyperlane_deployment="[environment]"}
- startTime: now-1h
- queryType: instant5.2: Spot-Check Roots at Key Indices
Compare validator and relayer roots at three points: first fixed index, middle, and latest.
index=[INDEX]
validator_root=$(curl -s "https://hyperlane-[environment]-[origin]-validator-0.s3.us-east-1.amazonaws.com/checkpoint_${index}_with_id.json" | jq -r '.value.checkpoint.root')
relayer_root=$(curl -s "localhost:9090/merkle_proofs?domain_id=[domain_id]&leaf_index=${index}&root_index=${index}" | jq -r '.root')
echo "Index $index:"
echo " Validator: $validator_root"
echo " Relayer: 0x$relayer_root"
if [ "$validator_root" = "0x$relayer_root" ]; then echo " ✓ Match"; else echo " ❌ MISMATCH"; fiRun this for:
- First fixed index (e.g., 37352)
- Middle index (e.g., 39000)
- Latest index (e.g., 41172)
5.3: Verify Mismatch Metric is Clear
Use mcp__grafana__query_prometheus with:
- datasourceUid: grafanacloud-prom
- expr: hyperlane_merkle_root_mismatch{origin="[origin]"}
- startTime: now-1h
- queryType: instantExpected result: Empty result or value of 0.
5.4: Report Results
Present validation results in a table:
| Index | Location | Result |
| 37352 | First fixed | ✓ Match |
| 39000 | Middle | ✓ Match |
| 41172 | Latest | ✓ Match |
If still mismatched:
- Inform the user that additional entries may need fixing
- Suggest re-running
/investigate-merkle-root-mismatchto investigate further
API Reference
Relayer Endpoints
| Endpoint | Method | Description |
/merkle_tree_insertions | GET | List merkle tree insertions from DB |
/merkle_tree_insertions | POST | Insert/update merkle tree entries |
Request/Response Examples
POST /merkle_tree_insertions
Request:
{
"merkle_tree_insertions": [
{
"chain": 1101,
"insertion_block_number": 9891832,
"leaf_index": 1477,
"message_id": "0x4bb3e20db45366a6a360ad2639c5421ea622a69b89b2edb045aa97e2051529b7"
}
]
}Response (success):
{
"status": "success",
"data": {
"count": 1
}
}Common Issues
- Port-forward disconnected: Re-establish before applying fixes
- API returns error: Check the error message, verify domain_id and message_id format
- Relayer restart fails: Check kubectl access and pod status
- Fix didn't work: May have missed some mismatched indices, re-investigate
Runbook Reference
Full runbook: https://www.notion.so/hyperlanexyz/Merkle-Root-Mismatch-26a6d35200d680a2857dcd0b228d4ab7
In this repository49 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-registry-changesetSkill
- build-docker-imageSkill
- classify-onchain-ownerSkill
- code-reviewSkill
- debug-messageSkill
- debug-rpc-providerSkill
- debug-validator-checkpoint-inconsistencySkill
- denylist-stuck-messagesSkill
- fetch-linear-ticketSkill
- fetch-safe-tx-batchSkill
- find-docker-imageSkill
- fix-rpc-urlsSkill
- gcp-logsSkill
- hyperlane-message-utilsSkill
- hyperlane-utilsSkill
- inline-pr-commentsSkill
- investigate-merkle-root-mismatchSkill
- investigate-stuck-messagesSkill
- registry-yaml-sort-policySkill
- security-reviewSkill
- self-relay-hyperlane-messageSkill
- set-moonpay-standing-quotesSkill
- start-http-registrySkill
- stop-http-registrySkill
- svm-warp-alt-manageSkill
- svm-warp-program-upgradeSkill
- tob-reviewSkill
- verify-warp-contractsSkill
- warp-balancesSkill
- warp-deploy-fund-deployerSkill
- warp-deploy-init-routeSkill
- warp-deploy-nexusSkill
- warp-deploy-register-routeSkill
- warp-deploy-select-keysSkill
- warp-deploy-send-testSkill
- warp-deploy-update-ownersSkill
- warp-deploy-validate-ownersSkill
- warp-forkSkill
- warp-key-value-expansionSkill
- warp-manage-offchain-quotesSkill
- warp-route-checkSkill
- warp-run-logSkill
- warp-simulate-svm-txsSkill
- warp-update-extendSkill
- warp-update-proposeSkill
- warp-update-resolve-artifactsSkill
- warp-updateSkill
- warp-verify-onchain-configSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

