{"record":{"id":"a385fac14f773f5a","repo":"jdx/mise","slug":"cannot-replace-task-stub-directory-because-does","errorCode":null,"errorMessage":"cannot replace task stub directory because {} does not contain the generated stub for task {}","messagePattern":"cannot replace task stub directory because (.+?) does not contain the generated stub for task (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/generate/task_stubs.rs","lineNumber":299,"sourceCode":"                );\n            }\n        }\n        Ok(_) => bail!(\n            \"cannot write Windows launcher because {} is not a regular file\",\n            display_path(&launcher)\n        ),\n        Err(err) if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}\n        Err(err) => return Err(err.into()),\n    }\n    Ok(())\n}\n\nfn validate_generated_stub_directory(path: &Path, expected: &str, task: &Task) -> Result<()> {\n    let default = path.join(\"_default\");\n    match fs::symlink_metadata(&default) {\n        Ok(metadata)\n            if metadata.file_type().is_file() && file::read_to_string(&default)? == expected => {}\n        _ => bail!(\n            \"cannot replace task stub directory because {} does not contain the generated stub for task {}\",\n            display_path(path),\n            task.display_name\n        ),\n    }\n\n    validate_generated_stub_tree(path)?;\n    Ok(())\n}\n\nfn validate_generated_stub_tree(path: &Path) -> Result<usize> {\n    let mut files = 0;\n    for entry in fs::read_dir(path)? {\n        let entry = entry?;\n        let entry_path = entry.path();\n        let metadata = fs::symlink_metadata(&entry_path)?;\n        if metadata.file_type().is_dir() {\n            let child_files = validate_generated_stub_tree(&entry_path)?;","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/cli/generate/task_stubs.rs#L281-L317","documentation":"A directory occupies the stub's target path, so mise would replace it with the nested stub directory — but only after proving it owns the tree: `<path>/_default` must exist and byte-equal the stub this run would generate. The check failed (missing _default, or content differs, e.g. because a previous run used a different --mise-bin), so the directory is treated as the user's and left untouched.","triggerScenarios":"bin/<parent>/ exists from an older run or manual creation, and bin/<parent>/_default is absent, edited, or generated with different content (notably a different --mise-bin or mise version) than the current run produces.","commonSituations":"Changing --mise-bin between regenerations; contributor hand-edited the _default stub; directory created by another tool at the same path.","solutions":["Inspect bin/<parent>/_default; if edited or stale, remove the whole directory (`git rm -r bin/<parent>`) and rerun to regenerate","Keep --mise-bin (and mise version) stable across regenerations so stub contents keep matching","If the directory is yours, move it aside or rename the task"],"exampleFix":"# before: generated with --mise-bin=./mise before, now default `mise`\n$ mise generate task-stubs\n# error: bin/build does not contain the generated stub for task build\n\n# after\n$ git rm -r bin/build\n$ mise generate task-stubs","handlingStrategy":"validation","validationCode":"#!/bin/bash\n# a directory may occupy a stub path only if it holds our current _default stub\nfor d in $(mise tasks ls --json 2>/dev/null | jq -r '.[]!.name' | grep ':' | cut -d: -f1 | sort -u); do\n  if [ -d \"bin/$d\" ]; then\n    grep -q 'generated by mise task-stubs' \"bin/$d/_default\" 2>/dev/null \\\n      || { echo \"bin/$d/_default missing or foreign\" >&2; exit 1; }\n  fi\ndone\nmise generate task-stubs","typeGuard":null,"tryCatchPattern":"if ! mise generate task-stubs; then\n  echo 'stub directory not recognized as generated — git rm -r it and rerun with the same --mise-bin' >&2\n  exit 1\nfi","preventionTips":["Pin --mise-bin to one value in the project docs/CI so regenerated stubs always match","Regenerate stubs with the same mise version that wrote them, or delete the tree first","Never edit bin/<parent>/_default by hand"],"tags":["mise","task-stubs","migration","ownership","generate"],"backgroundTag":"generated-file-ownership-conflict","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}