{"record":{"id":"c904f21c21693900","repo":"jdx/mise","slug":"explicit-task-name-was-just-found","errorCode":null,"errorMessage":"explicit task name was just found","messagePattern":"explicit task name was just found","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":1150,"sourceCode":"                None => Vec::new(),\n            };\n            for task in inferred_tasks {\n                // Explicit project tasks replace provider inference. Preserve the provider-scoped\n                // name as an alias, but never merge provider fields into the explicit definition.\n                if tasks.contains_key(&task.name) {\n                    let available_aliases = task\n                        .aliases\n                        .into_iter()\n                        .filter(|alias| {\n                            !tasks.contains_key(alias)\n                                && !tasks\n                                    .values()\n                                    .any(|explicit| explicit.aliases.contains(alias))\n                        })\n                        .collect::<Vec<_>>();\n                    tasks\n                        .get_mut(&task.name)\n                        .expect(\"explicit task name was just found\")\n                        .aliases\n                        .extend(available_aliases);\n                    continue;\n                }\n                let explicit_name = task\n                    .aliases\n                    .iter()\n                    .find(|alias| tasks.contains_key(*alias))\n                    .cloned()\n                    .or_else(|| {\n                        task.aliases.iter().find_map(|alias| {\n                            tasks.iter().find_map(|(name, explicit)| {\n                                (explicit.file.is_some() && strip_task_extension(name) == alias)\n                                    .then(|| name.clone())\n                            })\n                        })\n                    })\n                    .or_else(|| {","sourceCodeStart":1132,"sourceCodeEnd":1168,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/config/mod.rs#L1132-L1168","documentation":"mise panics with 'explicit task name was just found' when collecting alias tasks and `tasks.get_mut(&task.name)` returns `None`. The loop has just inserted (or verified) an entry keyed by each explicit task's own name, so looking it up again must succeed; a `None` means the task's name key was not actually present in the map, breaking the alias-collection invariant in config parsing (src/config/mod.rs:1150).","triggerScenarios":"Parsing mise task files where a task's aliases are being merged into the explicit task entry, but the earlier insertion keyed under `task.name` was skipped or the name was mutated between insert and lookup — e.g. duplicate task definitions, a task defined only via an alias, or a refactor changing how explicit tasks are first inserted into `tasks`.","commonSituations":"A mise.toml or task file defines a task whose `name` differs from the key it was inserted under; two files define tasks that collide on name and the second overwrites/removes the first; a contributor changes the insertion loop upstream of the alias merge.","solutions":["Verify every explicit task is inserted into `tasks` keyed by its own `name` before the alias-extension loop runs","Check for duplicate task names across config files that could overwrite the earlier entry","If name can change, look up the entry by the same key used at insertion time rather than re-deriving `task.name`","Make the insertion a `shift_insert`/entry API immediately adjacent to the get_mut so the invariant is locally obvious"],"exampleFix":"// before\ntasks.entry(task.name.clone()).or_insert_with(|| task.clone())\n    .aliases.extend(available_aliases);\n// (original) get_mut panics if key missing\ntasks.get_mut(&task.name).expect(\"explicit task name was just found\")\n     .aliases.extend(available_aliases);","handlingStrategy":"type-guard","validationCode":"if !tasks.contains_key(&task.name) { return Err(anyhow!(\"task {} missing from map before alias merge\", task.name)); }","typeGuard":"fn get_task<'a>(tasks: &'a mut Tasks, name: &str) -> Option<&'a mut Task> { tasks.get_mut(name) }","tryCatchPattern":null,"preventionTips":["Insert every explicit task under its own name before alias merging","Use the entry API to combine insert and alias extension in one step","Test configs with duplicate/colliding task names"],"tags":["rust","tasks","config","panic","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}