{"record":{"id":"745adf5be2d4c221","repo":"BigPizzaV3/CodexPlusPlus","slug":"dream-skin-theme-backup-belongs-to-a-different-con","errorCode":null,"errorMessage":"Dream Skin theme backup belongs to a different config.toml","messagePattern":"Dream Skin theme backup belongs to a different config\\.toml","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin.rs","lineNumber":300,"sourceCode":"    }\n    if uses_native_chrome_theme(theme) {\n        restore_backup_setting(desktop, &backup, \"appearanceLightCodeThemeId\")?;\n        restore_backup_setting(desktop, &backup, \"appearanceLightChromeTheme\")?;\n    } else {\n        desktop[\"appearanceLightCodeThemeId\"] = value(\"codex\");\n        desktop[\"appearanceLightChromeTheme\"] =\n            Item::Value(Value::InlineTable(target_chrome_theme(theme, profile)));\n    }\n    write_config(config_path, document.to_string().as_bytes())\n}\n\nfn restore_base_theme(config_path: &Path, backup_path: &Path) -> anyhow::Result<()> {\n    if !backup_path.exists() {\n        return Ok(());\n    }\n    let backup = read_backup(backup_path)?;\n    if backup.config_path != config_path.to_string_lossy() {\n        bail!(\"Dream Skin theme backup belongs to a different config.toml\");\n    }\n\n    let existing = read_config_or_empty(config_path)?;\n    let mut document = parse_config(&existing, config_path)?;\n    if document.get(\"desktop\").is_none() {\n        document[\"desktop\"] = Item::Table(Table::new());\n    }\n    let desktop = desktop_table_mut(&mut document)?;\n    for key in APPEARANCE_KEYS {\n        match backup.values.get(key).and_then(Option::as_deref) {\n            Some(serialized) => {\n                desktop[key] = parse_backup_item(&backup, serialized)\n                    .with_context(|| format!(\"failed to restore Dream Skin setting {key}\"))?;\n            }\n            None => {\n                desktop.remove(key);\n            }\n        }","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin.rs#L282-L318","documentation":"restore_base_theme reads the JSON backup and compares its stored config_path against the current config.toml path (textual comparison via to_string_lossy). A mismatch means the backup was captured against a different config.toml; restoring would corrupt this one, so it refuses. When no backup file exists, restore is a clean no-op.","triggerScenarios":"CODEX_HOME changed, or config.toml was moved or renamed, between applying a theme and restoring it; a state dir reused with a different config path layout.","commonSituations":"Users relocating their codex home; machine migration; one state dir shared by several profiles.","solutions":["Restore while pointed at the same config.toml path that was active when the theme was applied","If the old path is gone for good, delete the stale backup file - restore then no-ops cleanly","Set CODEX_HOME consistently across apply and restore"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn backup_targets_config(backup_path: &std::path::Path, config_path: &std::path::Path) -> bool {\n    std::fs::read(backup_path)\n        .ok()\n        .and_then(|b| serde_json::from_slice::<serde_json::Value>(&b).ok())\n        .and_then(|v| {\n            v.get(\"config_path\")?\n                .as_str()\n                .map(|s| s == config_path.to_string_lossy())\n        })\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep CODEX_HOME stable across apply and restore cycles","Delete orphaned dream-skin backups when config.toml relocates","The comparison is textual - symlinked homes that resolve differently will mismatch"],"tags":["dream-skin","backup","config-mismatch","rust"],"backgroundTag":"backup-identity-mismatch","analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}