{"record":{"id":"37c948af254e09b9","repo":"Hmbown/CodeWhale","slug":"error-rollback-failed-the-pre-import-document-is-preserved","errorCode":null,"errorMessage":"{error:#}; ROLLBACK FAILED — the pre-import document is preserved at {}","messagePattern":"(.+?); ROLLBACK FAILED — the pre-import document is preserved at (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/cli/src/config_bundles.rs","lineNumber":1091,"sourceCode":"    let original_config = store.config.clone();\n    let backup_path = if target\n        .try_exists()\n        .with_context(|| format!(\"checking config target {}\", target.display()))?\n    {\n        Some(create_collision_safe_backup(&target)?)\n    } else {\n        None\n    };\n\n    let mut target_written = false;\n    let apply_result = apply(candidate, store, &mut target_written);\n    if let Err(error) = apply_result {\n        store.config = original_config;\n        let rollback = rollback_import_target(&target, backup_path.as_deref(), target_written)\n            .and_then(|()| store.reload());\n        match rollback {\n            Ok(()) => bail!(\"{error:#}; rolled back to the pre-import document\"),\n            Err(_) => bail!(\n                \"{error:#}; ROLLBACK FAILED — the pre-import document is preserved at {}\",\n                backup_path\n                    .as_deref()\n                    .map(Path::display)\n                    .map(|path| path.to_string())\n                    .unwrap_or_else(\n                        || \"<no prior file; remove the new target manually>\".to_string()\n                    )\n            ),\n        }\n    }\n\n    Ok(ImportReceipt {\n        plan,\n        backup_path,\n        target,\n    })\n}","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/config_bundles.rs#L1073-L1109","documentation":"The most dangerous import outcome: the apply step failed AND the rollback also failed (rollback_import_target or store.reload() errored). The library raises the original error plus \"ROLLBACK FAILED\" and points at the backup file path where the pre-import document was preserved, so the user can restore manually.","triggerScenarios":"apply(candidate, ...) errors during apply_bundle/run_import, then rollback_import_target (restoring the backup or deleting a config created during the transaction) or store.reload() also fails — e.g. the backup path is gone, the disk is full, or the config file is locked/read-only.","commonSituations":"Disk-full or permission problems preventing the backup restore; another process deleting the backup mid-import; the target config file made read-only by another tool; a config created during the transaction that could not be removed.","solutions":["Manually restore the pre-import document from the backup path printed in the error message.","Check disk space and file permissions on the config location, fix them, and retry the import.","Ensure no other process is holding the config file or the backup open/locked.","After restoring, diff the live config against the backup to confirm state, then re-run the corrected import."],"exampleFix":"// recovery\ncp ~/.config/codewhale/config.toml.bak ~/.config/codewhale/config.toml\n# then retry the import after fixing disk/permissions","handlingStrategy":"fallback","validationCode":"// Before importing, verify the config dir is writable and has free space:\n// df -h ~/.config/codewhale && test -w ~/.config/codewhale/config.toml && echo ok","typeGuard":null,"tryCatchPattern":"match run_import(&bundle, &store, scope) {\n    Err(e) if e.to_string().contains(\"ROLLBACK FAILED\") => {\n        let backup = extract_backup_path(&e.to_string());\n        eprintln!(\"restore manually: cp {backup:?} <config path>, then diff before retrying\");\n    }\n    other => other?,\n}","preventionTips":["Ensure ample disk space and write permissions on the config directory before imports.","Never delete or lock the .bak backup files the importer creates.","Close other processes that hold the config file open during import.","After any failed import, diff the live config against the backup to verify state."],"tags":["transaction","rollback","data-loss","import","config-bundles"],"backgroundTag":"file-write-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}