{"record":{"id":"35ae2754636a90ec","repo":"Hmbown/CodeWhale","slug":"seed-backup","errorCode":null,"errorMessage":"seed backup","messagePattern":"seed backup","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/config/src/tests.rs","lineNumber":4203,"sourceCode":"            .lines()\n            .any(|line| line.trim_start().starts_with(\"api_key =\"))\n    );\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());","sourceCodeStart":4185,"sourceCodeEnd":4221,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/config/src/tests.rs#L4185-L4221","documentation":"A test assertion helper: fs::write(&path, ...).expect(\"seed backup\") panics if writing the seed backup file fails in the scrub_plaintext_api_keys_from_config_backup test at crates/config/src/tests.rs:4203. It is not a library error — it indicates the test fixture could not create its backup file.","triggerScenarios":"The temp directory was deleted before the write, the path is a directory, the disk is full, or permission denied on the fixture path.","commonSituations":"Flaky CI with parallel tests clobbering a shared path; tests refactored to share one tempdir where one test removed it.","solutions":["Ensure each test creates its own tempfile::tempdir() instead of sharing a path across tests.","Check the io::Error in the panic message: NotFound -> missing dir, PermissionDenied -> fs perms, IsADirectory -> wrong path.","Run the single test in isolation (cargo test -p codewhale-config <name>) to rule out parallel-test interference."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"assert!(backup_path.parent().is_some());\nstd::fs::create_dir_all(backup_path.parent().unwrap())?;","typeGuard":null,"tryCatchPattern":"if let Err(e) = fs::write(&backup_path, contents) {\n    panic!(\"seed backup failed ({e:?}): is the tempdir still alive?\");\n}","preventionTips":["Give each test its own tempfile::tempdir()","Keep the TempDir alive until all fixture writes finish","Read the io::Error kind in the panic before guessing"],"tags":["test","filesystem","fixture","io"],"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-22T11:17:16.035Z"}