jdx/mise · error

cannot write task stub because {} is not a generated task st

Error message

cannot write task stub because {} is not a generated task stub

What it means

A regular file already exists at the stub path but its content is neither the stub this run would generate nor the legacy stub form (the legacy exception covers only a legacy-path leaf with the old marker-less body). mise only overwrites stubs it can recognize as its own, so a foreign or hand-modified file stops the run before anything is written.

Source

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

            Err(err) => return Err(err.into()),
        }
    }

    for stub in stubs {
        match fs::symlink_metadata(&stub.path) {
            Ok(metadata) if metadata.file_type().is_dir() => {
                validate_generated_stub_directory(&stub.path, &stub.output, stub.task)?;
                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)?;
        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())) => {}

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. If the file is the project's own, move it out of the way: `git mv bin/<task> bin/<task>.sh`
  2. If it is a mise stub you edited, revert the edits (`git checkout -- bin/<task>`) or delete it so mise regenerates
  3. Fold the needed behavior into the task definition rather than the generated stub, then rerun `mise generate task-stubs`

Example fix

# before
$ mise generate task-stubs
# error: cannot write task stub because bin/test is not a generated task stub

# after (bin/test was our own script)
$ git mv bin/test scripts/run-tests.sh
$ mise generate task-stubs
Defensive patterns

Strategy: type-guard

Validate before calling

#!/bin/bash
# any existing stub-shaped path must carry the mise marker
for f in $(mise tasks ls --json 2>/dev/null | jq -r '.[]!.name' | tr ':' '/'); do
  [ -f "bin/$f" ] && ! grep -q 'generated by mise task-stubs' "bin/$f" \
    && { echo "bin/$f is not a generated stub" >&2; exit 1; }
done
mise generate task-stubs

Type guard

is_mise_stub() {
  [ "$(head -1 "$1")" = '#!/bin/sh' ] && [ "$(sed -n 2p "$1")" = '# generated by mise task-stubs' ]
}

Try / catch

if ! mise generate task-stubs; then
  grep -q 'is not a generated task stub' /dev/stdin <<<"$err" 2>/dev/null
  echo 'rename or remove the foreign file under bin/, then rerun' >&2
  exit 1
fi

Prevention

When it happens

Trigger: bin/<task> is a project script predating a task of the same name; a previously generated stub was edited by hand; a stub from a run with a different --mise-bin was modified afterwards.

Common situations: Adopting task-stubs in a repo whose bin/ already has scripts; a contributor tweaked a generated stub locally and committed it.

Related errors


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