jdx/mise · error

cannot write task stub because

Error message

cannot write task stub because {} is not a regular file

What it means

mise checks the type of any existing entry at a task stub path before writing. This error means the path exists as something that is not a regular file or directory (e.g. a FIFO, socket, or device), so a stub cannot be written there and mise aborts.

Solutions

  1. Inspect the path with `ls -la` and remove the non-regular entry
  2. Rerun `mise generate task-stubs` after cleanup
  3. If the path is on a filesystem that mangles file types, relocate the tasks directory

Example fix

// before
$ ls -la .mise/tasks/build
srwxr-xr-x build  # socket
// after
$ rm .mise/tasks/build && mise generate task-stubs
Defensive patterns

Strategy: validation

Validate before calling

const st = fs.lstatSync(stubPath, { throwIfNoEntry: false });
if (st && !st.isFile() && !st.isDirectory()) {
  throw new Error(`${stubPath} is not a regular file; remove it before generating stubs`);
}

Type guard

const isRegularFileOrAbsent = (p: string): boolean => {
  const st = fs.lstatSync(p, { throwIfNoEntry: false });
  return !st || st.isFile();
};

Prevention

When it happens

Trigger: Running `mise generate task-stubs` where a stub target path holds a special filesystem object instead of a regular file.

Common situations: Corrupted checkouts, leftover named pipes from build tooling, or unusual filesystems at the tasks directory path.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/bfa7f2a94412de90. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/generate/task_stubs.rs:547

            Ok(metadata) if metadata.file_type().is_dir() => {
                validate_generated_stub_directory(&stub.path, &stub.output, stub.task, launchers)?;
                migrations.insert(StubMigration::Directory(stub.path.clone()));
            }
            Ok(metadata) if metadata.file_type().is_symlink() => bail!(
                "cannot write task stub because {} is a symbolic link",
                display_path(&stub.path)
            ),
            Ok(metadata) if metadata.file_type().is_file() => {
                let existing = file::read_to_string(&stub.path)?;
                let legacy_leaf = stub.legacy_path == stub.path && existing == stub.legacy_output;
                if existing != stub.output && !legacy_leaf {
                    bail!(
                        "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) => {}

View on GitHub (pinned to 533346cc37)