{"record":{"id":"65212586e642a7a7","repo":"BigPizzaV3/CodexPlusPlus","slug":"sidebar-restore-requires-a-codex-home","errorCode":null,"errorMessage":"sidebar restore requires a Codex home","messagePattern":"sidebar restore requires a Codex home","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-data/src/storage.rs","lineNumber":908,"sourceCode":"fn restore_backups(\n    backups: &[Value],\n    fallback_db_path: &Path,\n    allowed_db_paths: &[PathBuf],\n    codex_home: Option<&Path>,\n) -> anyhow::Result<()> {\n    for backup in backups {\n        let Some(tables) = backup[\"tables\"].as_object() else {\n            continue;\n        };\n        let source_db = backup_source_db(backup, fallback_db_path, allowed_db_paths)?;\n        let db = Connection::open_with_flags(&source_db, OpenFlags::SQLITE_OPEN_READ_WRITE)?;\n        validate_restore_tables(tables)?;\n        detect_restore_conflicts(&db, tables)?;\n        detect_file_restore_conflicts(tables)?;\n        preflight_restore_rows(&db, tables)?;\n        if let Some(sidebar) = tables.get(\"__sidebar\") {\n            let home = codex_home\n                .ok_or_else(|| anyhow::anyhow!(\"sidebar restore requires a Codex home\"))?;\n            crate::provider_sync::validate_thread_sidebar_snapshot(home, sidebar)?;\n        }\n    }\n\n    for backup in backups {\n        let Some(tables) = backup[\"tables\"].as_object() else {\n            continue;\n        };\n        let source_db = backup_source_db(backup, fallback_db_path, allowed_db_paths)?;\n        let mut db = Connection::open_with_flags(&source_db, OpenFlags::SQLITE_OPEN_READ_WRITE)?;\n        let tx = db.transaction()?;\n        restore_rows(&tx, tables)?;\n        tx.commit()?;\n        if let Some(files) = tables.get(\"__files\").and_then(Value::as_array) {\n            for file in files {\n                let Some(path) = file.get(\"path\").and_then(Value::as_str) else {\n                    continue;\n                };","sourceCodeStart":890,"sourceCodeEnd":926,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6/crates/codex-plus-data/src/storage.rs#L890-L926","documentation":"restore_backups can restore the special `__sidebar` table only if the caller supplies the Codex home directory, because validating the sidebar snapshot requires reading the live catalog under that home. When a backup contains a `__sidebar` table but `codex_home` is None, this error is raised before any backup is written.","triggerScenarios":"Calling restore_backups (e.g. from `undo`) with a backup whose tables include `__sidebar` while passing codex_home: None — typically via an API path or command that omits the home argument.","commonSituations":"Scripted or programmatic undo calls that don't pass the Codex home; restoring a backup taken with sidebar snapshotting into an environment where home detection was skipped; CLI flags omitting the home override.","solutions":["Pass the Codex home directory (e.g. ~/.codex) to restore_backups so the sidebar snapshot can be validated","Strip the `__sidebar` table from the backup if you intentionally want to restore without sidebar validation","Use the standard undo entry point which resolves the default Codex home automatically","Re-create the backup without sidebar snapshot if the target environment has no Codex home"],"exampleFix":"// before\nrestore_backups(db, &backups, None)?;\n// after\nrestore_backups(db, &backups, Some(&codex_home))?;","handlingStrategy":"validation","validationCode":"let needs_home = backup[\"tables\"].as_object().map_or(false, |t| t.contains_key(\"__sidebar\"));\nif needs_home && codex_home.is_none() {\n    return Err(\"__sidebar backup requires codex_home\".into());\n}","typeGuard":null,"tryCatchPattern":"match restore_backups(db, &backups, codex_home) {\n    Err(e) if e.to_string().contains(\"sidebar restore requires a Codex home\") => {\n        // retry with Some(default_codex_home()) or strip __sidebar\n    }\n    other => other?,\n}","preventionTips":["Always thread codex_home through restore call sites; default to ~/.codex when unset","Check backup tables for __sidebar before deciding whether home is needed","Prefer the high-level undo entry point which resolves home automatically"],"tags":["rust","arguments","backup-restore"],"backgroundTag":"missing-required-argument","analyzedSha":"b1ed92e5e4a2d74095d4b8db5af43cef7acba9c6","analyzedAt":"2026-09-19T23:35:21.129Z","contentChangedAt":"2026-09-19T23:35:21.129Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}