jdx/mise · error
package plugin state parent
Error message
package plugin state parent
What it means
`save_state_at` calls `path.parent().expect("package plugin state parent")` before creating directories for the plugin state file. `Path::parent()` returns `None` only for root paths (`/`) or empty paths, so the panic means the plugin's state path has no parent directory — typically because the configured plugin state location is a filesystem root or empty.
Solutions
- Configure the plugin state path to a real nested file (e.g. /path/to/state/plugin.json), not a root or bare name
- Log/print `state_path()` before saving to see what it resolves to
- Change the code to map a missing parent to a descriptive error rather than a panic
Example fix
// before
let path = env_state_dir.unwrap_or_default().join(""); // resolves to ""
// after
let path = env_state_dir.unwrap_or(default_dir).join("plugin.json"); Defensive patterns
Strategy: validation
Validate before calling
let p = state_path();
if p.parent().is_none() {
return Err(anyhow!("plugin state path {:?} has no parent directory", p));
} Type guard
fn has_parent(p: &Path) -> bool { p.parent().is_some() } Prevention
- Configure state paths as full nested file paths, never a root or bare name
- Check env vars that template the state directory for empty values
- Log the resolved state path at debug level
When it happens
Trigger: Calling save_state (src/system/packages/plugin.rs:167) when `state_path()` resolves to `/` or an empty/relative-single-component path with no directory prefix, e.g. a misconfigured state directory like `MISE_..._STATE_PATH=/` or an unset variable producing `""`.
Common situations: Environment variable or config pointing the plugin state file at a mount root; empty path templating in config; running from a chroot with a root-level state path.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- a provided source resolves to a path
- a validated copy_link has a staged parent
- at least one bin path should exist
- config index exists
- declaring bootstrap config is loaded
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/5b3fd8eea6b9e8b0.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/plugin.rs:167
crate::file::display_path(path)
);
}
if state.manager != manager {
bail!(
"package plugin ownership state {} belongs to manager '{}', not '{manager}'",
crate::file::display_path(path),
state.manager
);
}
Ok(state)
}
fn load_state(&self) -> Result<PackagePluginState> {
Self::load_state_at(&self.state_path(), &self.name)
}
fn save_state_at(path: &std::path::Path, state: &PackagePluginState) -> Result<()> {
crate::file::create_dir_all(path.parent().expect("package plugin state parent"))?;
let mut contents = serde_json::to_vec_pretty(state)?;
contents.push(b'\n');
crate::file::write_atomic(path, contents)
}
fn save_state(&self, state: &PackagePluginState) -> Result<()> {
Self::save_state_at(&self.state_path(), state)
}
pub(crate) fn supports_uninstall(&self) -> bool {
self.plugin
.plugin_path
.join("hooks/package_uninstall.lua")
.exists()
}
fn sync_lookup_path() -> Vec<PathBuf> {
let mut paths: Vec<PathBuf> = std::env::var_os("PATH")View on GitHub (pinned to 533346cc37)