{"record":{"id":"1e8ee271bccb81dd","repo":"Hmbown/CodeWhale","slug":"session-goal-store-dir-was-not-created","errorCode":null,"errorMessage":"Session goal store {dir} was not created","messagePattern":"Session goal store (.+?) was not created","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_manager.rs","lineNumber":1334,"sourceCode":"                    dir.display()\n                ),\n            ));\n        }\n        Ok(Some(dir))\n    }\n\n    fn ensure_session_goals_dir(&self) -> std::io::Result<PathBuf> {\n        if let Some(dir) = self.checked_existing_session_goals_dir()? {\n            return Ok(dir);\n        }\n        let dir = self.session_goals_dir();\n        match fs::create_dir(&dir) {\n            Ok(()) => {}\n            Err(error) if error.kind() == io::ErrorKind::AlreadyExists => {}\n            Err(error) => return Err(error),\n        }\n        self.checked_existing_session_goals_dir()?.ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\"Session goal store {} was not created\", dir.display()),\n            )\n        })\n    }\n\n    fn validated_session_goal_path(&self, session_id: &str) -> std::io::Result<PathBuf> {\n        let id = self.validated_session_id(session_id)?;\n        Ok(self.session_goals_dir().join(format!(\"{id}.json\")))\n    }\n\n    fn checked_existing_session_goal_file(path: &Path) -> std::io::Result<bool> {\n        let metadata = match fs::symlink_metadata(path) {\n            Ok(metadata) => metadata,\n            Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(false),\n            Err(error) => return Err(error),\n        };\n        if metadata.file_type().is_symlink() || !metadata.is_file() {","sourceCodeStart":1316,"sourceCodeEnd":1352,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/session_manager.rs#L1316-L1352","documentation":"After attempting fs::create_dir on the goals directory (tolerating AlreadyExists), the code re-verifies the directory via checked_existing_session_goals_dir and errors with NotFound 'Session goal store ... was not created' if the check still cannot see a valid directory. This is an internal invariant failure: creation was expected to succeed (or already exist) yet the validation pass found nothing. Note checked_* also rejects symlinks, so a pre-existing symlink at the path lands here too.","triggerScenarios":"Calling ensure/create for the goal store when create_dir reports success or AlreadyExists but the subsequent symlink_metadata-based check returns None (path vanished, or path is a symlink treated as absent) — e.g. a race deletes the directory between the two calls.","commonSituations":"Another process concurrently cleaning the data directory; antivirus/sync tools removing freshly created dirs; a symlink existing at the path when create_dir hit AlreadyExists; filesystem permission oddities on network mounts.","solutions":["Re-run the operation — transient races usually resolve on a second attempt","Check for a symlink or file at the goals path; remove it so create_dir can make a real directory","Inspect permissions on the parent directory and ensure no concurrent cleaner deletes the data dir","If it persists, report as a bug — create_dir succeeding but the dir being absent is an environment race"],"exampleFix":"null","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for attempt in 0..3 {\n    match manager.ensure_goal_store() {\n        Ok(()) => break,\n        Err(e) if attempt < 2 && e.kind() == io::ErrorKind::NotFound => {\n            std::thread::sleep(std::time::Duration::from_millis(200));\n        }\n        Err(e) => return Err(e.into()),\n    }\n}","preventionTips":["Avoid running concurrent cleanup jobs against the data directory while the app runs","Exclude the data directory from aggressive antivirus/sync tooling","Remove symlinks at store paths so AlreadyExists doesn't mask an invalid entry"],"tags":["filesystem","race-condition","internal-invariant","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}