{"record":{"id":"67740bc075c258e6","repo":"benbjohnson/litestream","slug":"iterate-snapshots-for-crash-recovery-validation","errorCode":null,"errorMessage":"iterate snapshots for crash recovery validation: %w","messagePattern":"iterate snapshots for crash recovery validation: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":647,"sourceCode":"\t\t\t}\n\t\t\tif txid == 0 {\n\t\t\t\treturn fmt.Errorf(\"cannot resume follow mode: database exists but no -txid file found; delete the database to re-restore: %s\", opt.OutputPath)\n\t\t\t}\n\t\t\t// Validate saved TXID is still reachable. If the earliest snapshot\n\t\t\t// starts after our saved TXID, retention has pruned the history\n\t\t\t// and we can't catch up incrementally.\n\t\t\tsnapshotItr, itrErr := r.Client.LTXFiles(ctx, SnapshotLevel, 0, false)\n\t\t\tif itrErr != nil {\n\t\t\t\treturn fmt.Errorf(\"cannot validate saved TXID for crash recovery: %w\", itrErr)\n\t\t\t}\n\n\t\t\tvar latestSnapshot *ltx.FileInfo\n\t\t\tfor snapshotItr.Next() {\n\t\t\t\tlatestSnapshot = snapshotItr.Item()\n\t\t\t}\n\t\t\tif err := snapshotItr.Err(); err != nil {\n\t\t\t\t_ = snapshotItr.Close()\n\t\t\t\treturn fmt.Errorf(\"iterate snapshots for crash recovery validation: %w\", err)\n\t\t\t}\n\t\t\t_ = snapshotItr.Close()\n\n\t\t\tif latestSnapshot != nil {\n\t\t\t\tif latestSnapshot.MinTXID > txid {\n\t\t\t\t\treturn fmt.Errorf(\"cannot resume follow mode: saved TXID %s is behind the earliest snapshot (min TXID %s); replica history has been pruned -- delete %s and %s-txid to re-restore\", txid, latestSnapshot.MinTXID, opt.OutputPath, opt.OutputPath)\n\t\t\t\t}\n\t\t\t\tif txid > latestSnapshot.MaxTXID {\n\t\t\t\t\treturn fmt.Errorf(\"cannot resume follow mode: saved TXID %s is ahead of latest snapshot (max TXID %s); delete %s and %s-txid to re-restore\", txid, latestSnapshot.MaxTXID, opt.OutputPath, opt.OutputPath)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tr.Logger().Info(\"resuming follow mode from crash recovery\", \"txid\", txid, \"output\", opt.OutputPath)\n\t\t\treturn r.follow(ctx, opt.OutputPath, txid, opt.FollowInterval)\n\t\t}\n\t}\n\n\t// Ensure output path does not already exist.","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L629-L665","documentation":"While iterating snapshots for follow-mode crash recovery validation, the iterator reported an error after iteration (itr.Err). The remote listing partially failed, so the saved TXID's reachability could not be confirmed.","triggerScenarios":"Thrown at replica.go:647 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check replica backend health","Restart litestream to retry validation"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}