jdx/mise · error · eyre::Report

directive requires exactly one argument

Error message

directive requires exactly one argument

What it means

For unquoted arguments, parse_argument requires exactly one whitespace-separated token (value.split_whitespace().count() != 1 fails). A use or module directive carrying two or more bare words cannot name a single path, so parsing aborts.

Source

Thrown at src/task/workspace/go.rs:199

        bail!("directive requires one argument");
    }
    if let Some(value) = value.strip_prefix('"') {
        let Some(value) = value.strip_suffix('"') else {
            bail!("unterminated interpreted Go string");
        };
        return unescape_go_string(value);
    }
    if let Some(value) = value.strip_prefix('`') {
        let Some(value) = value.strip_suffix('`') else {
            bail!("unterminated raw Go string");
        };
        if value.contains('`') {
            bail!("unexpected raw Go string delimiter");
        }
        return Ok(value.to_string());
    }
    if value.split_whitespace().count() != 1 {
        bail!("directive requires exactly one argument");
    }
    Ok(value.to_string())
}

fn unescape_go_string(value: &str) -> Result<String> {
    let mut characters = value.chars();
    let mut unescaped = String::new();
    while let Some(character) = characters.next() {
        if character == '"' {
            bail!("unexpected interpreted Go string delimiter");
        }
        if character != '\\' {
            unescaped.push(character);
            continue;
        }
        let escape = characters
            .next()
            .ok_or_else(|| eyre::eyre!("unterminated Go string escape"))?;

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Split into one directive per entry: `use ./api` then `use ./worker` (or one per line inside a use (...) block)
  2. Use Go's block form for many entries
  3. If a path contains spaces, quote it as one interpreted string \"./my dir\"

Example fix

# before (go.work)
use ./api ./worker

# after
use (
    ./api
    ./worker
)
Defensive patterns

Strategy: validation

Validate before calling

fn is_single_token(token: &str) -> bool {
    token.starts_with('"') || token.starts_with('`') || token.split_whitespace().count() == 1
}

for arg in directive_arguments { assert!(is_single_token(arg)); }

Type guard

fn is_one_directive_argument(token: &str) -> bool {
    token.starts_with('"') || token.starts_with('`') || token.split_whitespace().count() == 1
}

Try / catch

Err(report) if report.to_string().contains("requires exactly one argument") => {
    // split multi-word directives into one use per token and re-parse
    for word in arguments.split_whitespace() { push_use(word); }
}

Prevention

When it happens

Trigger: go.work line `use ./api ./worker` (two directories on one directive); a go.mod `module example.com/foo extra`; entries where a trailing unquoted comment marker survived (e.g. `use ./api # note` after comment stripping leaves two tokens if '#' was not a // comment).

Common situations: Trying to list multiple modules on one line the way array syntax allows elsewhere; pasting a path plus annotation; converting from another format that joined entries with spaces.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/8e7b9c5ffe121070. Report an issue: GitHub.