jdx/mise · error

Cannot use :task syntax without a monorepo root

Error message

Cannot use :task syntax without a monorepo root

What it means

The ':task' syntax explicitly scopes a task to the current monorepo package, so it is only meaningful when a config file establishes a monorepo root. When expand_colon_task_syntax finds no config with monorepo_root() == Some(true), any colon-prefixed reference is rejected because there is no monorepo context to resolve it against.

Solutions

  1. Add/verify a root mise.toml at the repo root that establishes the monorepo root
  2. Use the plain task name instead: `mise run task`
  3. If not in a monorepo, cd to the package directory and run the task without ':' prefix
  4. Check config is loaded/trusted: `mise trust` and inspect `mise config ls`

Example fix

// before
mise run :build   # in a project with no monorepo root
// after
mise run build
# or add a root mise.toml marking the monorepo root
Defensive patterns

Strategy: validation

Validate before calling

mise config ls | grep -q . || echo 'no config loaded'; test -f mise.toml || echo 'no root mise.toml (monorepo root likely missing)'

Try / catch

if ! mise run "$TASK" 2>/dev/null; then mise run "${TASK#:}"; fi

Prevention

When it happens

Trigger: Running `mise run :task` (or any reference starting with ':') in a project where no loaded config file is marked as a monorepo root (no root mise.toml declaring the workspace root).

Common situations: Using monorepo task syntax in a standalone (non-monorepo) project; running from a subdirectory whose root config is missing or untrusted; forgetting to add a root mise.toml that defines the monorepo root.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/task/task_load_context.rs:210

    if !is_colon_pattern && task.contains('/') && task.contains(':') {
        bail!(
            "relative path syntax '{}' is not supported, use '//{}' or ':task' for current directory",
            task,
            task
        );
    }

    // Get the monorepo root config file.
    let monorepo_root = config
        .config_files
        .values()
        .find(|cf| cf.monorepo_root() == Some(true))
        .and_then(|cf| cf.project_root());

    // If not in monorepo context, only expand if it's a colon pattern (error), otherwise return as-is
    if monorepo_root.is_none() {
        if is_colon_pattern {
            bail!("Cannot use :task syntax without a monorepo root");
        }
        return Ok(task.to_string());
    }

    // We're in a monorepo context
    let monorepo_root = monorepo_root.unwrap();

    // Task names are keyed to project roots: the directories of configs in
    // scope plus declared [monorepo].config_roots, which may hold only file
    // tasks and no config. Scope to the nearest such root above cwd, not cwd
    // itself; the monorepo root bounds the walk and counts as a root.
    if let Some(cwd) = &*crate::dirs::CWD {
        let scope_dir: &Path = if cwd.starts_with(&monorepo_root) {
            let roots: Vec<PathBuf> = config
                .config_files
                .values()
                .filter_map(|cf| cf.project_root())
                .chain(config.monorepo_config_root_dirs(None).unwrap_or_default())

View on GitHub (pinned to 533346cc37)