jdx/mise · error

relative path syntax

Error message

relative path syntax '{}' is not supported, use '//{}'  or ':task' for current directory

What it means

In monorepo pattern matching, patterns must either be plain task names or explicit monorepo patterns starting with '//' (workspace-root path) or ':' (current directory). A pattern containing both '/' and ':' is rejected as ambiguous relative-path syntax, with a hint to use '//...' or ':task'.

Solutions

  1. Use '//pkg/util:build' to reference the task from the workspace root
  2. Use ':build' if the task is in the current directory
  3. Drop the path entirely and use the plain task name if it is unambiguous

Example fix

// before
mise run pkg/util:build

// after
mise run //pkg/util:build
Defensive patterns

Strategy: validation

Validate before calling

function normalizeTaskPattern(pat) {
  if (pat.includes('/') && pat.includes(':') && !pat.startsWith('//') && !pat.startsWith(':')) {
    return '//' + pat.replace(/^\.\//, '');
  }
  return pat;
}

Prevention

When it happens

Trigger: Passing a pattern like `./pkg/util:build` or `pkg/util:build` (relative path + task, not starting with '//' or ':') to task matching, e.g. `mise run pkg/util:build` or as a `depends` entry.

Common situations: Users guessing monorepo task syntax and writing a filesystem-relative path instead of the supported '//path:task' or ':task' forms.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/task/mod.rs:3513

                .iter()
                .filter(|(name, _)| {
                    name.split_once('#').is_some_and(|(project, task)| {
                        project_matcher.is_match(project)
                            && task_name_matches(&task_matcher, task, false)
                    })
                })
                .map(|(_, task)| task)
                .unique()
                .collect());
        }

        // === Monorepo pattern matching ===
        // Only patterns starting with '//' or ':' are monorepo patterns
        // Reject patterns that look like monorepo paths but use wrong syntax (have / and : but don't start with // or :)
        if !pat.starts_with("//") && !pat.starts_with(':') {
            // Check if this looks like an attempt at a monorepo path with wrong syntax
            if pat.contains('/') && pat.contains(':') {
                bail!(
                    "relative path syntax '{}' is not supported, use '//{}'  or ':task' for current directory",
                    pat,
                    pat
                )
            }
            // If it doesn't contain glob syntax or ':', it's a simple task name
            if !pat.contains(['*', '?', '[', '{']) && !pat.contains("...") && !pat.contains(':') {
                // Prefer exact name matches; only fall back to extension-stripped
                // matches when there is no exact match. Otherwise a TOML task
                // "hello" and an auto-discovered file task "hello.sh" would both
                // match `mise run hello` and run the script twice (#10298).
                let exact: Vec<&T> = self
                    .iter()
                    .filter(|(k, _)| k.as_str() == pat)
                    .map(|(_, v)| v)
                    .collect();
                if !exact.is_empty() {
                    return Ok(exact);

View on GitHub (pinned to 533346cc37)