jdx/mise · error
cannot create task stub directory because
Error message
cannot create task stub directory because {} is not a directory What it means
When creating nested task stubs, mise walks every ancestor directory of each stub path and requires each to be a real directory (or a legacy stub file queued for migration into a directory). This error means an ancestor exists as a non-directory file, so the stub's directory structure cannot be created.
Solutions
- Remove or rename the file occupying the intermediate path so mise can create the directory
- Ensure the file is recognized as a legacy generated stub (its content must match generated output) so it gets migrated
- Restructure task names/paths so nested components don't collide with existing files
Example fix
// before .mise/tasks/build # regular file, but build/x needs build/ to be a directory // after rm .mise/tasks/build && mise generate task-stubs
Defensive patterns
Strategy: validation
Validate before calling
for (const parent of ancestorsOf(stubPath)) {
const st = fs.lstatSync(parent, { throwIfNoEntry: false });
if (st && !st.isDirectory()) {
throw new Error(`${parent} blocks directory creation; remove or migrate it first`);
}
} Try / catch
try {
execSync('mise generate task-stubs');
} catch (e) {
if (String(e).includes('is not a directory')) {
console.error('A path component exists as a file; remove/rename it and rerun');
}
} Prevention
- Migrate to nested layouts in one step via mise's own migration rather than mixing layouts
- Do not create files whose names collide with planned subdirectories
- Run generation after pulling layout changes before committing
When it happens
Trigger: Running `mise generate task-stubs` with nested stub paths where an intermediate path component exists as a regular file, e.g. a file named `.mise/tasks` or a file where a subdirectory like `tasks/build` is needed.
Common situations: A previously generated flat stub file occupies a path that nested layout now needs as a directory but which was not recognized as a migratable stub; users created a file with the same name as a planned subdirectory.
Related errors
- cannot create nested task stubs because
- cannot write task stub because
- cannot create nested task stubs because
- cannot write native task stub launchers: mise-shim.exe was…
- cannot write task stub because
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/0803c16ed3ad0323.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/generate/task_stubs.rs:560
"cannot write task stub because {} is not a generated task stub",
display_path(&stub.path)
);
}
}
Ok(_) => bail!(
"cannot write task stub because {} is not a regular file",
display_path(&stub.path)
),
Err(err) if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}
Err(err) => return Err(err.into()),
}
validate_launcher_path(stub, launchers)?;
for parent in stub.path.ancestors().skip(1) {
match fs::symlink_metadata(parent) {
Ok(metadata)
if metadata.file_type().is_dir()
|| migrations.contains(&StubMigration::File(parent.to_path_buf())) => {}
Ok(_) => bail!(
"cannot create task stub directory because {} is not a directory",
display_path(parent)
),
Err(err)
if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}
Err(err) => return Err(err.into()),
}
if parent == dir {
break;
}
}
}
Ok(migrations.into_iter().collect())
}
/// Refuse to replace a launcher beside a stub that mise did not write.
///
/// The stub path is the user's choice, so `bin/<task>.cmd` is a name a project may already beView on GitHub (pinned to 533346cc37)