jdx/mise · error
plugin task name should be registered before spawning
Error message
plugin task name should be registered before spawning
What it means
mise runs plugin operations (install/update/uninstall across many plugins) concurrently in a tokio JoinSet, tracking a HashMap<Id, String> from spawned task id to plugin name. take_plugin_name removes and returns the name for a finished task and expects it to have been registered by spawn_plugin_task (src/cli/plugins/mod.rs:21-37). The expect fires if a completed task's id is missing from the map — bookkeeping between spawns and joined results diverged.
Source
Thrown at src/cli/plugins/mod.rs:24
use eyre::{Report, Result, WrapErr, eyre};
use tokio::task::{Id, JoinSet};
use crate::config::Config;
pub(crate) mod install;
mod link;
mod ls;
mod ls_remote;
mod uninstall;
mod update;
type PluginTaskResult = Result<()>;
type PluginTaskNames = HashMap<Id, String>;
fn take_plugin_name(task_names: &mut PluginTaskNames, id: Id) -> String {
task_names
.remove(&id)
.expect("plugin task name should be registered before spawning")
}
fn spawn_plugin_task<F>(
tasks: &mut JoinSet<PluginTaskResult>,
task_names: &mut PluginTaskNames,
plugin: impl Into<String>,
task: F,
) where
F: Future<Output = PluginTaskResult> + Send + 'static,
{
let task = tasks.spawn(task);
task_names.insert(task.id(), plugin.into());
}
async fn join_plugin_tasks(
mut tasks: JoinSet<PluginTaskResult>,
mut task_names: PluginTaskNames,
operation: &'static str,View on GitHub (pinned to 6f52dcdf99)
Solutions
- If hit as a user: update mise — internal concurrency bookkeeping bug; retry the plugin operation once after the panic since plugin state may be partially applied
- As a contributor: always spawn via spawn_plugin_task so the id is registered, and never consume JoinSet results outside join_plugin_tasks
- Add a regression test with a mix of panicking and succeeding tasks (see the existing tests in src/cli/plugins/mod.rs)
- Report at https://github.com/jdx/mise/issues with the panic backtrace
Example fix
// before: spawning directly, id never registered tasks.spawn(install_plugin(plugin.clone())); // later: take_plugin_name(&mut task_names, id) -> panic // after: route through the helper spawn_plugin_task(&mut tasks, &mut task_names, plugin.clone(), install_plugin(plugin));
Defensive patterns
Strategy: validation
Prevention
- Retry the plugin operation after a panic — plugin state may be partially applied, and mise plugins ls shows current state
- Contributors: always spawn plugin work through spawn_plugin_task so ids are registered
- Pin released versions; report backtraces upstream
When it happens
Trigger: Only a code change that polls the JoinSet without going through spawn_plugin_task's registration, or that takes a name twice for the same id; current code registers on every spawn and consumes each joined id exactly once (success, error, and panic/JoinError paths all route through take_plugin_name). Users running `mise plugins update|install|uninstall` in a correctly built mise cannot trigger it.
Common situations: Contributors adding new parallel plugin flows that call tasks.join_next_with_id() directly or forget task_names insertion; broken builds. The module's own tests (panicked_plugin_task_does_not_cancel_other_tasks) pin the intended behavior.
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
- enabled accounts were prepared
- configured notifications came from managed files
- configured notifications prepared services
- system files were preflighted when not skipped
- BootstrapPart values have clap names
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/20ac484a10755f54.
Report an issue: GitHub.