jdx/mise · error

cannot create nested task stubs because {} is not the genera

Error message

cannot create nested task stubs because {} is not the generated stub for task {}

What it means

For a task whose stub location changed (parent task now written to `<parent>/_default`), mise migrates away the file at the old flat path — but only after proving it is its own: the content must equal the current stub (`#!/bin/sh` + `# generated by mise task-stubs` + exec line) or the legacy one (same, without the marker line). It matches neither, so mise treats it as the user's file and refuses to overwrite it.

Source

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

    for path in &paths {
        if !seen.insert(path) {
            bail!(
                "multiple tasks map to task stub path {}",
                display_path(path)
            );
        }
    }
    Ok(paths)
}

fn validate_stub_paths(dir: &Path, stubs: &[TaskStub<'_>]) -> 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 9dcfcaa0dc)

Solutions

  1. Inspect the file (`cat bin/<legacy path>`); if it holds custom logic you need, move it into the task definition (mise.toml [tasks] or tasks/*.toml) instead of the stub
  2. If it is disposable or stale, remove it: `git rm bin/<legacy path>` and rerun `mise generate task-stubs`
  3. If the name is load-bearing, rename the task so the paths stop colliding

Example fix

# before: bin/build was hand-edited after generation
$ mise generate task-stubs
# error: cannot create nested task stubs because bin/build is not the generated stub for task build

# after
$ git rm bin/build
$ mise generate task-stubs   # writes bin/build/_default fresh
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/bash
# refuse to migrate over a file mise cannot recognize as its own stub
for f in bin/*; do
  [ -f "$f" ] || continue
  if [ -x "$f" ] && ! sed -n '2p' "$f" | grep -q 'generated by mise task-stubs' \
     && ! head -1 "$f" | grep -q '^#!/bin/sh'; then
    : # unrelated script — presence is fine, mise will refuse only if it occupies a legacy stub path
  fi
done
mise generate task-stubs

Type guard

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

Try / catch

if ! mise generate task-stubs; then
  echo 'a file under bin/ is not a generated stub — inspect, then git rm it' >&2
  exit 1
fi

Prevention

When it happens

Trigger: bin/<legacy path> is a hand-edited stub (someone customized the previously generated script) or an unrelated project script that happens to sit at the legacy path, and a run of `mise generate task-stubs` now wants the nested layout.

Common situations: Repo upgraded mise after contributors edited generated stubs; a pre-mise build script named identically to a new task.

Related errors


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