{"record":{"id":"4d343e959cd39a0e","repo":"Hmbown/CodeWhale","slug":"scrub-backup","errorCode":null,"errorMessage":"scrub backup","messagePattern":"scrub backup","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/config/src/tests.rs","lineNumber":4205,"sourceCode":"    );\n    assert!(backup.contains(\"api_key_env = \\\"OPENROUTER_API_KEY\\\"\"));\n    assert!(backup.contains(\"auth_mode = \\\"api_key\\\"\"));\n    assert!(backup.contains(\"default_text_model = \\\"deepseek-v4-pro\\\"\"));\n}\n\n#[test]\nfn config_backup_scrub_repairs_an_existing_plaintext_backup() {\n    let dir = tempfile::tempdir().expect(\"tempdir\");\n    let path = dir.path().join(CONFIG_FILE_NAME);\n    fs::write(&path, \"model = \\\"new-model\\\"\\n\").expect(\"seed config\");\n    let backup_path = config_backup_path(&path);\n    fs::write(\n        &backup_path,\n        \"api_key = \\\"old-test-credential\\\"\\nmodel = \\\"old-model\\\"\\n\",\n    )\n    .expect(\"seed backup\");\n\n    scrub_plaintext_api_keys_from_config_backup(&path).expect(\"scrub backup\");\n\n    let backup = fs::read_to_string(backup_path).expect(\"read backup\");\n    assert!(!backup.contains(\"old-test-credential\"), \"{backup}\");\n    assert!(!backup.contains(\"api_key\"), \"{backup}\");\n    assert!(backup.contains(\"model = \\\"old-model\\\"\"));\n}\n\n#[test]\nfn config_store_save_preserves_comments() {\n    let dir = tempfile::tempdir().expect(\"tempdir\");\n    let config_path = dir.path().join(CONFIG_FILE_NAME);\n    let original = \"# my model\\nmodel = \\\"deepseek-v4-flash\\\"\\n# end comment\\n\";\n    fs::write(&config_path, original).expect(\"write config\");\n\n    let mut store = ConfigStore::load(Some(config_path.clone())).expect(\"load config store\");\n    store.config.model = Some(\"deepseek-v4-pro\".to_string());\n    store.save().expect(\"save\");\n","sourceCodeStart":4187,"sourceCodeEnd":4223,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/config/src/tests.rs#L4187-L4223","documentation":"Second expect in the same test: fs::write(&backup_path, ...).expect(\"scrub backup\") is actually labeled on the write of the backup contents; the expect(\"scrub backup\") on the following line belongs to scrub_plaintext_api_keys_from_config_backup itself. A panic here means either the fixture write failed or the scrub function returned an Err while cleaning plaintext api_key entries from the config backup file.","triggerScenarios":"scrub_plaintext_api_keys_from_config_backup fails when the backup file is unreadable, unparseable as TOML, or cannot be rewritten; the fixture write can also fail for the same reasons as 2844.","commonSituations":"Changing the backup format so scrub's TOML parse fails; a regression in scrub leaving the file locked or read-only; CI filesystem issues.","solutions":["Read the wrapped io/parse error in the panic; if it comes from scrub, verify the backup content is valid TOML the scrubber accepts.","Confirm scrub_plaintext_api_keys_from_config_backup still rewrites the file atomically after parsing.","Run the test alone to exclude parallel interference."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let backup_toml: toml::Value = toml::from_str(&fs::read_to_string(&backup_path)?)?;\n// valid TOML before handing it to scrub","typeGuard":null,"tryCatchPattern":"scrub_plaintext_api_keys_from_config_backup(&path)\n    .unwrap_or_else(|e| panic!(\"scrub backup failed: {e}; is the backup valid TOML?\"));","preventionTips":["Keep backup fixtures valid TOML matching what scrub parses","Verify scrub still rewrites the file after parse-refactors","Run scrubbing tests in isolation when debugging"],"tags":["test","config","security","scrub"],"backgroundTag":"file-write-failed","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}