{"record":{"id":"a5f39cc200c1c8b4","repo":"stalwartlabs/stalwart","slug":"migration-aborted-message","errorCode":null,"errorMessage":"Migration aborted: {message}","messagePattern":"Migration aborted: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/migration/src/lib.rs","lineNumber":95,"sourceCode":"        ValueClass::Any(AnyClass {\n            subspace: SUBSPACE_PROPERTY,\n            key: vec![0u8],\n        }),\n        DATABASE_SCHEMA_VERSION.serialize(),\n    );\n\n    server\n        .store()\n        .write(batch.build_all())\n        .await\n        .caused_by(trc::location!())?;\n\n    Ok(())\n}\n\nfn abort(message: &str) -> ! {\n    eprintln!(\"Migration aborted: {message}\");\n    panic!(\"Migration aborted: {message}\");\n}\n\nasync fn is_new_install(server: &Server) -> trc::Result<bool> {\n    for subspace in [\n        SUBSPACE_QUEUE_MESSAGE,\n        SUBSPACE_REPORT_IN,\n        SUBSPACE_REPORT_OUT,\n        SUBSPACE_PROPERTY,\n    ] {\n        let mut has_data = false;\n\n        server\n            .store()\n            .iterate(\n                IterateParams::new(\n                    AnyKey {\n                        subspace,\n                        key: vec![0u8],","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/stalwartlabs/stalwart/blob/e96200385781a6a9995a8b839ac27d6c75a983ee/crates/migration/src/lib.rs#L77-L113","documentation":"The migration routine's `abort` helper deliberately stops a migration with a human-readable reason, printing to stderr and panicking. It is used whenever preconditions for a safe migration are not met, ensuring the migration stops before modifying data.","triggerScenarios":"Any precondition check inside the migration flow (invoked via try_migrate) calls `abort(reason)` — e.g. the database is in a state the migration cannot handle, or a required earlier migration step was skipped.","commonSituations":"Migrating a partially-upgraded database; running migrations out of order; a manual intervention step (documented in UPGRADING) was not completed before running the migrator.","solutions":["Read the {message} printed to stderr — it names the exact failed precondition.","Complete the manual step referenced in the UPGRADING documentation for your version.","Restore a backup and re-run migrations in the prescribed order.","File an issue with the message if the precondition appears satisfied."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// run migrations only after verifying preconditions\nif !preconditions_met(&server).await { eprintln!(\"fix migration preconditions first\"); std::process::exit(1); }","typeGuard":null,"tryCatchPattern":"// catch the panic from abort in a wrapper\nlet result = std::panic::catch_unwind(|| run_migration_blocking());\nif result.is_err() { eprintln!(\"migration aborted, restore backup\"); }","preventionTips":["Read stderr output of the migrator — abort always prints the reason.","Follow UPGRADING.md manual steps in order for every release.","Run migrations in a staging copy of the database first.","Keep backups so an aborted migration can be rolled back cleanly."],"tags":["database","migration","panic"],"backgroundTag":"invalid-state-transition","analyzedSha":"e96200385781a6a9995a8b839ac27d6c75a983ee","analyzedAt":"2026-09-06T22:07:17.982Z","contentChangedAt":"2026-09-06T22:07:17.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}