Hmbown/CodeWhale · error
Runtime store root
Error message
Runtime store root
What it means
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.
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
Example fix
// before
data_dir: self.store.event_lock_path.parent().expect("Runtime store root").to_path_buf(),
// after
data_dir: self
.store
.event_lock_path
.parent()
.expect("Runtime store root: event_lock_path must include a parent directory")
.to_path_buf(), Defensive patterns
Strategy: validation
Validate before calling
debug_assert!(self.store.event_lock_path.parent().is_some(), "event_lock_path must have a parent directory");
Type guard
fn has_parent(p: &Path) -> bool { p.parent().is_some() } Try / catch
let root = self.store.event_lock_path.parent().ok_or_else(|| anyhow!("Runtime store root missing: {}", self.store.event_lock_path.display()))?; Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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`.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- event recovery buffer fits u64
- event transaction runs once
- provider authority checked above
- snapshots carry one removal token per rule
- turn monitor exits normally only after assigning a terminal…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e00beed4c961a89e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:5153
pub fn attach_task_manager(&self, task_manager: crate::task_manager::SharedTaskManager) {
*self.task_manager.lock() = Arc::downgrade(&task_manager);
}
/// Identity of the actual Runtime store, not a model-supplied session label.
pub(crate) fn task_execution_identity(&self) -> (String, Arc<RuntimeProcessOwnerLock>) {
(
runtime_execution_scope(&self.store.owner_id, &self.store.event_lock_path),
self._process_owner_lock.clone(),
)
}
pub(crate) fn session_store_binding(&self) -> RuntimeStoreBinding {
RuntimeStoreBinding {
data_dir: self
.store
.event_lock_path
.parent()
.expect("Runtime store root")
.to_path_buf(),
execution_scope: self.task_execution_identity().0,
}
}
pub(crate) async fn close_execution_admission(&self) {
let _admission = self.config_admission.write().await;
self.cancel_token.cancel();
let _loading = self.engine_load.lock().await;
}
/// Close admission, then drain the existing engines and terminal receipt
/// monitors. Ownership stays attached to this Runtime until its last user
/// drops it, including any actual execution still awaiting shutdown.
pub(crate) async fn shutdown_and_wait(&self) -> Result<()> {
let _drain = self.shutdown_drain.lock().await;
self.close_execution_admission().await;
let (engines, active_turns) = {View on GitHub (pinned to 73e0f67d83)