jdx/mise · error

cannot replace task stub directory because {} does not conta

Error message

cannot replace task stub directory because {} does not contain the generated stub for task {}

What it means

A directory occupies the stub's target path, so mise would replace it with the nested stub directory — but only after proving it owns the tree: `<path>/_default` must exist and byte-equal the stub this run would generate. The check failed (missing _default, or content differs, e.g. because a previous run used a different --mise-bin), so the directory is treated as the user's and left untouched.

Source

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

                );
            }
        }
        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 validate_generated_stub_directory(path: &Path, expected: &str, task: &Task) -> Result<()> {
    let default = path.join("_default");
    match fs::symlink_metadata(&default) {
        Ok(metadata)
            if metadata.file_type().is_file() && file::read_to_string(&default)? == expected => {}
        _ => bail!(
            "cannot replace task stub directory because {} does not contain the generated stub for task {}",
            display_path(path),
            task.display_name
        ),
    }

    validate_generated_stub_tree(path)?;
    Ok(())
}

fn validate_generated_stub_tree(path: &Path) -> Result<usize> {
    let mut files = 0;
    for entry in fs::read_dir(path)? {
        let entry = entry?;
        let entry_path = entry.path();
        let metadata = fs::symlink_metadata(&entry_path)?;
        if metadata.file_type().is_dir() {
            let child_files = validate_generated_stub_tree(&entry_path)?;

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Inspect bin/<parent>/_default; if edited or stale, remove the whole directory (`git rm -r bin/<parent>`) and rerun to regenerate
  2. Keep --mise-bin (and mise version) stable across regenerations so stub contents keep matching
  3. If the directory is yours, move it aside or rename the task

Example fix

# before: generated with --mise-bin=./mise before, now default `mise`
$ mise generate task-stubs
# error: bin/build does not contain the generated stub for task build

# after
$ git rm -r bin/build
$ mise generate task-stubs
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/bash
# a directory may occupy a stub path only if it holds our current _default stub
for d in $(mise tasks ls --json 2>/dev/null | jq -r '.[]!.name' | grep ':' | cut -d: -f1 | sort -u); do
  if [ -d "bin/$d" ]; then
    grep -q 'generated by mise task-stubs' "bin/$d/_default" 2>/dev/null \
      || { echo "bin/$d/_default missing or foreign" >&2; exit 1; }
  fi
done
mise generate task-stubs

Try / catch

if ! mise generate task-stubs; then
  echo 'stub directory not recognized as generated — git rm -r it and rerun with the same --mise-bin' >&2
  exit 1
fi

Prevention

When it happens

Trigger: bin/<parent>/ exists from an older run or manual creation, and bin/<parent>/_default is absent, edited, or generated with different content (notably a different --mise-bin or mise version) than the current run produces.

Common situations: Changing --mise-bin between regenerations; contributor hand-edited the _default stub; directory created by another tool at the same path.

Related errors


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