jdx/mise · error
package plugin ownership state {} belongs to manager '{}', n
Error message
package plugin ownership state {} belongs to manager '{}', not '{manager}' What it means
The persisted package plugin ownership state records which manager wrote it. load_state_at refuses to load a state file whose `manager` field does not match the manager currently requesting it, to avoid one package manager deleting or clobbering another's packages.
Source
Thrown at src/system/packages/plugin.rs:153
packages: BTreeMap::new(),
});
}
let state: PackagePluginState = serde_json::from_str(&crate::file::read_to_string(path)?)
.wrap_err_with(|| {
format!(
"failed to read package plugin ownership state {}",
crate::file::display_path(path)
)
})?;
if state.schema_version != STATE_SCHEMA_VERSION {
bail!(
"unsupported package plugin ownership state version {} in {}",
state.schema_version,
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)
}View on GitHub (pinned to afd2eddd3a)
Solutions
- Delete the ownership state file listed in the error so the new manager starts with clean state
- Re-run the package install/prune with the current manager to regenerate matching state
- Verify the manager name in your mise config matches the manager that originally wrote the state
- Manually uninstall packages tracked by the old manager before switching, then clear the state
Example fix
// before: state written by 'brew', config now says 'apt' # error: ... state ... belongs to manager 'brew', not 'apt' // after rm ~/.local/share/mise/plugins/myplugin/state.json mise plugins packages install myplugin foo # state recreated for 'apt'
Defensive patterns
Strategy: validation
Validate before calling
let state: OwnershipState = read_state(path)?;
if state.manager != current_manager { fs::remove_file(path)?; } Type guard
fn state_belongs_to(s: &OwnershipState, m: &str) -> bool { s.manager == m } Try / catch
match plugin.load_state().await {
Err(e) if e.to_string().contains("belongs to manager") => {
reset_state_for(current_manager); plugin.load_state().await
}
other => other,
} Prevention
- Keep one manager per plugin; rename managers only after clearing state
- Don't copy MISE_DATA_DIR state between machines using different package managers
- Uninstall tracked packages before switching a plugin's manager
When it happens
Trigger: The same state file path is used by two different package managers (state.manager differs from the manager argument), e.g. after renaming a manager, switching providers, or copying state between plugin/manager setups.
Common situations: Switching a plugin's package manager configuration (e.g. from brew to apt) while old ownership state remains; renaming a manager in config; sharing MISE_DATA_DIR between setups.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- unsupported package plugin ownership state version {} in {}
- pre_use hook is not implemented
- {tool}'s bin/install exited successfully but installed nothi
- asdf plugin '{plugin_name}' exists but '{tool_name}' is not
- vfox plugin '{plugin_name}' exists but '{tool_name}' is not
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/07164ba15d02fa32.
Report an issue: GitHub.