{"record":{"id":"3e021dcaf791e2fe","repo":"Hmbown/CodeWhale","slug":"store","errorCode":null,"errorMessage":"store","messagePattern":"store","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/release/src/check.rs","lineNumber":225,"sourceCode":"    fn a_future_timestamp_is_stale_not_permanently_fresh() {\n        let entry = UpdateCheckCache {\n            checked_at_unix: 2_000_000,\n            latest_tag: Some(\"v9.9.9\".to_string()),\n        };\n        assert!(!entry.is_fresh(1_000_000, 24));\n    }\n\n    #[test]\n    fn store_then_load_round_trips_and_survives_an_existing_file() {\n        let dir = tempfile::tempdir().expect(\"tempdir\");\n        let path = cache_path_in(dir.path());\n        assert_eq!(path.file_name().unwrap(), UPDATE_CHECK_CACHE_FILE);\n\n        let first = UpdateCheckCache {\n            checked_at_unix: 42,\n            latest_tag: Some(\"v0.9.5\".to_string()),\n        };\n        first.store(&path).expect(\"store\");\n        assert_eq!(UpdateCheckCache::load(&path), Some(first));\n\n        // Overwriting in place must not leave the temp file behind.\n        let second = UpdateCheckCache {\n            checked_at_unix: 99,\n            latest_tag: None,\n        };\n        second.store(&path).expect(\"overwrite\");\n        assert_eq!(UpdateCheckCache::load(&path), Some(second));\n        assert!(!path.with_extension(\"json.tmp\").exists());\n    }\n\n    #[test]\n    fn store_creates_a_missing_home_directory() {\n        let dir = tempfile::tempdir().expect(\"tempdir\");\n        let path = cache_path_in(&dir.path().join(\"nested\").join(\"home\"));\n        UpdateCheckCache::now(Some(\"v1.0.0\".to_string()))\n            .store(&path)","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/release/src/check.rs#L207-L243","documentation":"Test panic from `first.store(&path).expect(\"store\")`: UpdateCheckCache::store failed to persist the cache file. store creates the parent directory, writes a `json.tmp` temp file, then renames it into place; the expect fires when any of create_dir_all, fs::write, or rename returns an Err carrying its anyhow context.","triggerScenarios":"Calling UpdateCheckCache::store on a path whose parent cannot be created (permission denied), whose temp file cannot be written (full disk, read-only mount), or whose rename target is locked/blocked (e.g. cross-filesystem rename after some environments make the .tmp path behave unexpectedly).","commonSituations":"Running tests on a read-only home or filesystem; disk full; antivirus/backup tools holding the target file open so rename fails; nested-home edge cases where create_dir_all hits a permission wall.","solutions":["Read the anyhow context message from the panic/backtrace (\"failed to create …\", \"failed to write …\", \"failed to install …\") to identify which of the three steps failed.","Ensure the test's tempdir parent is writable; check permissions and free space on the backing filesystem.","If rename fails because the target is held open, close competing handles or retry; on exotic filesystems verify rename support for the tempdir location."],"exampleFix":"// before\nfirst.store(&path).expect(\"store\");\n// after — surface which step failed when debugging\nif let Err(e) = first.store(&path) {\n    panic!(\"store failed: {e:#}\"); // prints create/write/install context chain\n}","handlingStrategy":"try-catch","validationCode":"// verify the target directory is writable before storing\nlet dir = path.parent().unwrap();\nassert!(dir.exists() && !dir.metadata().unwrap().permissions().readonly());","typeGuard":"fn writable_dir(p: &Path) -> bool {\n    p.metadata().map(|m| !m.permissions().readonly()).unwrap_or(false)\n}","tryCatchPattern":"entry.store(&path).unwrap_or_else(|e| panic!(\"cache store failed: {e:#}\")); // anyhow context chain shows create/write/install step","preventionTips":["Store cache files under the user's home, not read-only system locations.","Treat store errors as non-fatal in production (fall back to skipping the cache), reserving hard failures for tests.","Check free disk space before first write on long-lived processes."],"tags":["rust","filesystem","atomic-write","test-panic"],"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"}