Skip to content

fix(migration-keeper): only MigrationNotInitialized means no snapshot - #1176

Merged
collinsezedike merged 1 commit into
drydocs:mainfrom
liutingqiu:fix/1131-migration-snapshot-error
Oct 20, 2026
Merged

collinsezedike merged 1 commit into
drydocs:mainfrom
liutingqiu:fix/1131-migration-snapshot-error

Conversation

@liutingqiu

Copy link
Copy Markdown
Contributor

Closes #1131

What was wrong

migration-keeper.ts classified a snapshot read failure with snapshotReadFailed = isTransientKeeperError(err). Any non-transient, non-MigrationNotInitialized failure — a decode/parse error, contract-not-found, a definitive simulation error, an HTTP 400/404 — therefore left snapshotReadFailed false, so hasMatchingSnapshot stayed false and the keeper fired begin_migration. That resets an already cooldown-elapsed snapshot's ledger_seq back to now, the exact harm the surrounding comment says must be avoided.

Fix

Only a confirmed MigrationNotInitialized means "this vault has no snapshot yet". Everything else is a read failure and is reported as retryable:

s snapshotReadFailed = !isMigrationNotInitializedError(err);

isMigrationNotInitializedError matches the three shapes that error arrives in: the contract identifier (MigrationNotInitialized), the reason tx.ts maps it to (Start a migration before calling migrate), and the raw contract code (Error(Contract, #19) — #19 in VAULT_CONTRACT_ERROR_MESSAGES). The comment now states that this deliberately does not defer to isTransientKeeperError: a non-transient but unrecognised read error is still not proof of absence.

Tests

migration-keeper.test.ts gains a case where get_migration_snapshot throws a definitive, non-transient error (contract not found: HTTP 404) and asserts:

  • sendTransaction was never called (no begin_migration)
  • the run reports a retryable failure containing "could not read the migration snapshot"

The existing transient-timeout test still passes, and so do the genuine-MigrationNotInitialized cases that must fall through to begin_migration.

Verification

$ pnpm lint && pnpm typecheck && pnpm test
# lint:       (no output)
# typecheck:  (no output)
# test:       23 files, 563 tests passed

The new test fails on the pre-fix commit (it observed a begin_migration submission) and passes after it.

@vercel

vercel Bot commented Oct 19, 2026

Copy link
Copy Markdown

@liutingqiu is attempting to deploy a commit to the Collins' projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@liutingqiu Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@liutingqiu

Copy link
Copy Markdown
Contributor Author

Verified locally on this branch before asking for review.

Full workspace suite, pnpm test (after pnpm --filter @meridian/shared build):

@meridian/shared              4 files   65 tests passed
@meridian/stellar-sdk-helpers 23 files 562 tests passed
@meridian/sdk                 5 files   68 tests passed
@meridian/strategies         35 files  716 tests passed
@meridian/api-core            5 files   73 tests passed
@meridian/api-local           2 files   39 tests passed
@meridian/web                40 files  360 tests passed
@meridian/api                 5 files   80 tests passed
------------------------------------------------------
119 files, 1963 tests passed, 0 failed

The regression test added here is migration-keeper.test.ts › reports a non-transient snapshot read error as retryable instead of assuming no snapshot. The bug: only MigrationNotInitialized should mean "no snapshot yet"; any other read failure was being treated the same way, so a transient RPC error silently skipped the migration and let the keeper proceed with stale state. The test drives a 404 from the contract read and asserts the keeper reports a retryable failure and does not call sendTransaction.

Diff is 34 lines in migration-keeper.ts plus the test: narrows the "not initialised" pattern to the three messages the contract actually returns (MigrationNotInitialized, Start a migration before calling migrate, Error(Contract, #19)).

Repro: pnpm --filter @meridian/shared build && pnpm --filter @meridian/stellar-sdk-helpers test.

@liutingqiu
liutingqiu force-pushed the fix/1131-migration-snapshot-error branch from 4c2592b to c9ea0af Compare October 20, 2026 02:07
@liutingqiu liutingqiu changed the title fix(migration-keeper): only MigrationNotInitialized means no snapshot (#1131) fix(migration-keeper): only MigrationNotInitialized means no snapshot Oct 20, 2026
@liutingqiu

Copy link
Copy Markdown
Contributor Author

The Commit Messages failure was only the 77-character subject line; I shortened it and left the code unchanged. The new workflow runs are waiting for maintainer approval (action_required), so CI cannot re-run yet. Could you approve the runs and take a look when you have a moment? Happy to adjust anything else.

@liutingqiu

Copy link
Copy Markdown
Contributor Author

@collinsezedike The only failing check on this PR is Vercel's Authorization required to deploy — it needs a member of the Collins' projects Vercel team to authorize the deployment (Vercel bot link above). Everything else is green: Lint & Typecheck, Test, Commit Messages and PR Title all pass, and the PR is mergeable. Could you authorize the deployment (or re-run Vercel) when you have a moment? Thanks!

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix, @liutingqiu. This is a solid contribution. If you'd like to pick up another open issue, there are several available in the tracker.

@collinsezedike
collinsezedike merged commit d49b1e4 into drydocs:main Oct 20, 2026
11 of 12 checks passed
@collinsezedike

Copy link
Copy Markdown
Collaborator

@liutingqiu thank you again for getting this over the line. If you are enjoying working on Meridian, starring the repository helps more contributors find the project and is much appreciated.

@liutingqiu

Copy link
Copy Markdown
Contributor Author

Thanks for the kind words and for reviewing the PR. I’ve enjoyed contributing to Meridian, and I’ll star the repository to help others discover the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Migration keeper treats a non-transient snapshot read error as no snapshot

2 participants