{"record":{"id":"e00beed4c961a89e","repo":"Hmbown/CodeWhale","slug":"runtime-store-root","errorCode":null,"errorMessage":"Runtime store root","messagePattern":"Runtime store root","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/runtime_threads.rs","lineNumber":5153,"sourceCode":"    pub fn attach_task_manager(&self, task_manager: crate::task_manager::SharedTaskManager) {\n        *self.task_manager.lock() = Arc::downgrade(&task_manager);\n    }\n\n    /// Identity of the actual Runtime store, not a model-supplied session label.\n    pub(crate) fn task_execution_identity(&self) -> (String, Arc<RuntimeProcessOwnerLock>) {\n        (\n            runtime_execution_scope(&self.store.owner_id, &self.store.event_lock_path),\n            self._process_owner_lock.clone(),\n        )\n    }\n\n    pub(crate) fn session_store_binding(&self) -> RuntimeStoreBinding {\n        RuntimeStoreBinding {\n            data_dir: self\n                .store\n                .event_lock_path\n                .parent()\n                .expect(\"Runtime store root\")\n                .to_path_buf(),\n            execution_scope: self.task_execution_identity().0,\n        }\n    }\n\n    pub(crate) async fn close_execution_admission(&self) {\n        let _admission = self.config_admission.write().await;\n        self.cancel_token.cancel();\n        let _loading = self.engine_load.lock().await;\n    }\n\n    /// Close admission, then drain the existing engines and terminal receipt\n    /// monitors. Ownership stays attached to this Runtime until its last user\n    /// drops it, including any actual execution still awaiting shutdown.\n    pub(crate) async fn shutdown_and_wait(&self) -> Result<()> {\n        let _drain = self.shutdown_drain.lock().await;\n        self.close_execution_admission().await;\n        let (engines, active_turns) = {","sourceCodeStart":5135,"sourceCodeEnd":5171,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/runtime_threads.rs#L5135-L5171","documentation":"Panic from `event_lock_path.parent()` in `session_store_binding`. `Path::parent()` returns None only when the path is a bare filename or root with no parent; the code asserts the configured event lock path always lives under a store root directory.","triggerScenarios":"The Runtime store's `event_lock_path` being misconfigured to a relative bare filename (no directory component), leaving `parent()` with nothing to return when `session_store_binding` is called.","commonSituations":"Config files or defaults setting the lock path without its parent directory after a config migration or typo like `event.lock` instead of `/path/to/store/event.lock`.","solutions":["Ensure `event_lock_path` is always an absolute path with a directory component","Validate the configured lock path at config load time (fail loud per repo convention)","Guard the call site with a check that returns a descriptive error instead of panicking"],"exampleFix":"// before\ndata_dir: self.store.event_lock_path.parent().expect(\"Runtime store root\").to_path_buf(),\n// after\ndata_dir: self\n    .store\n    .event_lock_path\n    .parent()\n    .expect(\"Runtime store root: event_lock_path must include a parent directory\")\n    .to_path_buf(),","handlingStrategy":"validation","validationCode":"debug_assert!(self.store.event_lock_path.parent().is_some(), \"event_lock_path must have a parent directory\");","typeGuard":"fn has_parent(p: &Path) -> bool { p.parent().is_some() }","tryCatchPattern":"let root = self.store.event_lock_path.parent().ok_or_else(|| anyhow!(\"Runtime store root missing: {}\", self.store.event_lock_path.display()))?;","preventionTips":["Always configure event_lock_path as an absolute path with a directory","Validate store paths at config load (fail loud) before the runtime starts","Never store bare filenames as lock paths"],"tags":["rust","panic","path","configuration","invariant"],"backgroundTag":"invalid-config-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}