jdx/mise · error
cannot create nested task stubs because
Error message
cannot create nested task stubs because {} is not the generated stub for task {} What it means
When migrating flat task stubs to nested ones, mise may need to replace a legacy stub path with a directory. If the legacy path exists as a regular file whose content is neither the current nor legacy generated stub output, mise refuses to overwrite a file it did not generate, protecting hand-written files from destruction.
Solutions
- Restore the legacy path's file content to the exact generated stub output (regenerate it with the old layout) so migration can proceed
- Delete or move the unrecognized file at the legacy path if it is not needed
- Check the file into a different location if it is hand-written, since mise will never overwrite non-generated files
Example fix
// before: hand-edited legacy stub #!/bin/sh mise x -- my-task "$@" # custom tweaks // after: regenerate or remove so it matches stub output rm .mise/tasks/build && mise generate task-stubs
Defensive patterns
Strategy: validation
Validate before calling
const legacy = fs.readFileSync(legacyStubPath, 'utf8');
if (legacyStubExists && legacy !== generatedOutput && legacy !== legacyOutput) {
throw new Error(`${legacyStubPath} was modified by hand; save it and remove before nested migration`);
} Try / catch
try {
execSync('mise generate task-stubs');
} catch (e) {
if (String(e).includes('is not the generated stub for task')) {
console.error('Back up the hand-edited legacy stub, delete it, rerun generation');
}
} Prevention
- Never hand-edit generated task stubs; edit the underlying task instead
- Regenerate stubs after changing layout (flat -> nested) before committing
- Treat stub files as generated artifacts in code review
- If a stub was customized, move the customization out before migrating
When it happens
Trigger: Running `mise generate task-stubs` where a task's legacy stub path (flat layout) exists as a file with user-modified or unrelated content, while the new layout places stubs in a directory of that name.
Common situations: Developers edited a previously generated stub by hand and later enabled nested task stubs; a checked-in script occupies the path that the nested stub directory needs; generated from an older mise version with different stub content.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- cannot write task stub because
- cannot write Windows launcher because
- cannot create nested task stubs because
- cannot create task stub directory because
- cannot write native task stub launchers: mise-shim.exe was…
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/9f4910f2fb39bc9a.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/generate/task_stubs.rs:509
display_path(path)
);
}
}
Ok(paths)
}
fn validate_stub_paths(
dir: &Path,
stubs: &[TaskStub<'_>],
launchers: &Launchers,
) -> Result<Vec<StubMigration>> {
let mut migrations = HashSet::new();
for stub in stubs.iter().filter(|stub| stub.legacy_path != stub.path) {
match fs::symlink_metadata(&stub.legacy_path) {
Ok(metadata) if metadata.file_type().is_file() => {
let existing = file::read_to_string(&stub.legacy_path)?;
if existing != stub.output && existing != stub.legacy_output {
bail!(
"cannot create nested task stubs because {} is not the generated stub for task {}",
display_path(&stub.legacy_path),
stub.task.display_name
);
}
migrations.insert(StubMigration::File(stub.legacy_path.clone()));
}
Ok(metadata) if metadata.file_type().is_dir() => {}
Ok(_) => bail!(
"cannot create nested task stubs because {} is not a directory",
display_path(&stub.legacy_path)
),
Err(err) if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}
Err(err) => return Err(err.into()),
}
}
for stub in stubs {View on GitHub (pinned to 533346cc37)