jdx/mise · error
plugin task name should be registered before spawning
Error message
plugin task name should be registered before spawning
What it means
A `.expect()` panic in `take_plugin_name` (src/cli/plugins/mod.rs:23). Every plugin task spawned via `spawn_plugin_task` must register a display name in `PluginTaskNames` keyed by the JoinSet task Id; `join_plugin_tasks` removes that name when the task finishes. Panicking means a completed task's Id was never registered — spawn bypassed the registration helper.
Solutions
- Spawn all plugin tasks through `spawn_plugin_task` so the name is registered before the task runs
- Ensure the name insert happens before `JoinSet::spawn` returns its Id
- Make take_plugin_name fall back to a placeholder (e.g. "<unknown plugin>") instead of panicking
Example fix
// before
task_names.remove(&id).expect("plugin task name should be registered before spawning")
// after
task_names.remove(&id).unwrap_or_else(|| "<unknown plugin>".to_string()) Defensive patterns
Strategy: type-guard
Validate before calling
debug_assert!(task_names.contains_key(&id), "plugin task name not registered for {id:?}"); Type guard
fn registered(task_names: &PluginTaskNames, id: &Id) -> bool { task_names.contains_key(id) } Try / catch
let name = task_names.remove(&id).unwrap_or_else(|| "<unregistered plugin>".into());
Prevention
- Route every spawn through spawn_plugin_task; never call JoinSet::spawn directly for plugin tasks
- Insert the task name before spawning, not after
- Add a unit test that joins at least one spawned plugin task
When it happens
Trigger: A plugin task spawned directly on the JoinSet (not via `spawn_plugin_task`), or registration failing/being skipped before `detach`, so `join_plugin_tasks` receives an unknown Id.
Common situations: New code paths spawning plugin tasks after a refactor; a spawn helper changed so names are inserted after the task already completed and were drained.
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
- artifact directory was initialized
- command wait must complete
- config index exists
- configured notifications came from managed files
- configured notifications prepared services
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/20ac484a10755f54.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/plugins/mod.rs:23
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 afd2eddd3a)