{"record":{"id":"c6b1fa75ed61df4e","repo":"jdx/mise","slug":"multiple-tasks-map-to-task-stub-path","errorCode":null,"errorMessage":"multiple tasks map to task stub path {}","messagePattern":"multiple tasks map to task stub path (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/generate/task_stubs.rs","lineNumber":182,"sourceCode":"        .collect::<Vec<_>>();\n    let paths = base_paths\n        .iter()\n        .enumerate()\n        .map(|(index, path)| {\n            if base_paths.iter().enumerate().any(|(other_index, other)| {\n                index != other_index && other != path && other.starts_with(path)\n            }) {\n                path.join(\"_default\")\n            } else {\n                path.clone()\n            }\n        })\n        .collect::<Vec<_>>();\n\n    let mut seen = HashSet::new();\n    for path in &paths {\n        if !seen.insert(path) {\n            bail!(\n                \"multiple tasks map to task stub path {}\",\n                display_path(path)\n            );\n        }\n    }\n    Ok(paths)\n}\n\nfn validate_stub_paths(dir: &Path, stubs: &[TaskStub<'_>]) -> Result<Vec<StubMigration>> {\n    let mut migrations = HashSet::new();\n    for stub in stubs.iter().filter(|stub| stub.legacy_path != stub.path) {\n        match fs::symlink_metadata(&stub.legacy_path) {\n            Ok(metadata) if metadata.file_type().is_file() => {\n                let existing = file::read_to_string(&stub.legacy_path)?;\n                if existing != stub.output && existing != stub.legacy_output {\n                    bail!(\n                        \"cannot create nested task stubs because {} is not the generated stub for task {}\",\n                        display_path(&stub.legacy_path),","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/cli/generate/task_stubs.rs#L164-L200","documentation":"`mise generate task-stubs` maps each task name to a path under --dir, moving a parent task that collides with a nested task to `<parent>/_default`. After that resolution two distinct tasks still produced the same file path; writing both would silently overwrite one stub with the other, so mise stops with the colliding path.","triggerScenarios":"A task set where distinct names fold onto one path: e.g. a task literally named `foo:_default` (file tasks/foo/_default.toml) alongside `foo` plus a nested `foo:bar` — the parent rule sends `foo` to foo/_default too; or names that differ only in separators name_to_path folds together.","commonSituations":"Adding nested tasks after a flat task list already exists; a tasks/ file whose directory-derived name collides with an explicitly named task; tasks defined in both mise.toml [tasks] and task files with matching names.","solutions":["List tasks with `mise tasks ls` and rename whichever task collides (change its name in mise.toml [tasks] or the tasks/ file name) so the paths differ","Remove the duplicate/leftover definition — check both [tasks] tables and files under tasks/","Point --dir at an empty directory and regenerate to confirm the collision is in task names, not stale stub files"],"exampleFix":"# before: tasks `foo`, `foo:bar`, and `foo:_default` (tasks/foo/_default.toml)\n$ mise generate task-stubs\n# error: multiple tasks map to task stub path bin/foo/_default\n\n# after: delete tasks/foo/_default.toml (or rename its task)\n$ git rm tasks/foo/_default.toml\n$ mise generate task-stubs","handlingStrategy":"validation","validationCode":"#!/bin/bash\n# flag tasks whose names fold to the same stub path (colon -> directory)\nmise tasks ls --json 2>/dev/null | jq -r '.[]!.name' \\\n  | tr ':' '/' | sort | uniq -d | while read -r dup; do\n    echo \"colliding stub path: bin/$dup\" >&2; exit 1\ndone\nmise generate task-stubs","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid task names ending in _default at any nesting level — that segment is reserved for parent stubs","Do not define the same task in both mise.toml [tasks] and a tasks/ file with an equivalent name","Re-run `mise generate task-stubs` in CI right after task-name changes so collisions surface immediately"],"tags":["mise","task-stubs","collision","tasks","generate"],"backgroundTag":"path-collision","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}