jdx/mise · error

cannot write Windows launcher because {} is not a regular fi

Error message

cannot write Windows launcher because {} is not a regular file

What it means

The Windows launcher path `<output>.cmd` exists but is not a regular file (directory, symlink, fifo...). mise cannot write the launcher there, and validation happens before the stub is written, so generation aborts cleanly.

Source

Thrown at src/cli/generate/tool_stub.rs:228

    /// for a script of its own, and nothing about that name says mise owns it. The stub itself is
    /// different: the user named it, so overwriting it is what they asked for.
    fn validate_windows_launcher(&self, stub_content: &str) -> Result<()> {
        if !wants_windows_launcher(stub_content) {
            return Ok(());
        }
        let Some(launcher) = super::windows_launcher_path(&self.output) else {
            return Ok(());
        };
        match fs::symlink_metadata(&launcher) {
            Ok(metadata) if metadata.file_type().is_file() => {
                if !super::is_generated_launcher(&file::read_to_string(&launcher)?) {
                    bail!(
                        "cannot write Windows launcher because {} is not a generated launcher",
                        display_path(&launcher)
                    );
                }
            }
            Ok(_) => bail!(
                "cannot write Windows launcher because {} is not a regular file",
                display_path(&launcher)
            ),
            Err(err) if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}
            Err(err) => return Err(err.into()),
        }
        Ok(())
    }

    fn get_tool_name(&self) -> String {
        self.output
            .file_name()
            .and_then(|name| name.to_str())
            .unwrap_or("tool")
            .to_string()
    }

    async fn generate_stub(&self) -> Result<String> {

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Remove the object at `<output>.cmd` (`rm -rf` for the directory case)
  2. Pick an `--output` whose `.cmd` sibling path is free
  3. Note: naming the output with an executable extension (.cmd/.bat/.exe) suppresses the sibling launcher entirely, since windows_launcher_path returns None for those

Example fix

# before
$ ls -ld bin/tool.cmd   # a directory
$ mise generate tool-stub --output bin/tool --url https://...
# error: bin/tool.cmd is not a regular file

# after
$ rm -rf bin/tool.cmd
$ mise generate tool-stub --output bin/tool --url https://...
Defensive patterns

Strategy: type-guard

Validate before calling

#!/bin/bash
OUT=bin/tool
[ -e "$OUT.cmd" ] && [ ! -f "$OUT.cmd" -o -L "$OUT.cmd" ] \
  && { echo "$OUT.cmd is not a regular file" >&2; exit 1; }
mise generate tool-stub --output "$OUT" --url "$URL"

Type guard

launcher_writable() {
  # 0 when <stub>.cmd is absent or a plain regular file
  [ ! -e "$1.cmd" ] || { [ -f "$1.cmd" ] && [ ! -L "$1.cmd" ]; }
}

Prevention

When it happens

Trigger: `mise generate tool-stub --output bin/tool` when bin/tool.cmd is a directory (accidental `mkdir bin/tool.cmd`) or other non-file object.

Common situations: Misnamed folders; mount points or symlinked directories occupying the launcher path.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/222d95f25702a26a. Report an issue: GitHub.