jdx/mise · error · eyre::Report

trimV requires exactly 1 argument

Error message

trimV requires exactly 1 argument

What it means

command_wrapper's content and executable are mutually exclusive: content is written verbatim as the launcher script, while executable generates a shell wrapper around the binary. Setting both is ambiguous and rejected at parse time.

Source

Thrown at crates/aqua-registry/src/template.rs:358

        Ok(Box::new(SemVerValue {
            major: version.nth(0).unwrap_or(0),
            minor: version.nth(1).unwrap_or(0),
            patch: version.nth(2).unwrap_or(0),
            original: clean_version.to_string(),
        }) as Box<dyn Value>)
    });

    registry.insert("title", |args| {
        if args.len() != 1 {
            bail!("title requires exactly 1 argument");
        }
        Ok(Box::new(StringValue(args[0].as_string().to_title_case())) as Box<dyn Value>)
    });

    registry.insert("trimV", |args| {
        if args.len() != 1 {
            bail!("trimV requires exactly 1 argument");
        }
        Ok(Box::new(StringValue(
            args[0].as_string().trim_start_matches('v').to_string(),
        )) as Box<dyn Value>)
    });

    registry.insert("trimPrefix", |args| {
        if args.len() != 2 {
            bail!("trimPrefix requires exactly 2 arguments");
        }
        let prefix = args[0].as_string();
        let text = args[1].as_string();
        Ok(Box::new(StringValue(
            text.strip_prefix(&prefix).unwrap_or(&text).to_string(),
        )) as Box<dyn Value>)
    });

    registry.insert("trimSuffix", |args| {

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Keep 'executable' and delete 'content' if you want a generated wrapper
  2. Keep 'content' and delete 'executable' if the launcher is fully hand-written

Example fix

# before
{"command_wrapper": ["tool", {"content": "#!/bin/bash\n...", "executable": "bin/tool"}]}
# after
{"command_wrapper": ["tool", {"executable": "bin/tool"}]}
Defensive patterns

Strategy: validation

Validate before calling

if opts.get("content").is_some() && opts.get("executable").is_some() {
    // reject before install: pick one
}

Type guard

fn wrapper_sets_exactly_one(opts: &serde_json::Map<String, Value>) -> bool {
    opts.get("content").is_some() ^ opts.get("executable").is_some()
}

Prevention

When it happens

Trigger: Options object containing both 'content' and 'executable' keys, e.g. while migrating a wrapper from inline script to binary wrapping and forgetting to remove the old key.

Common situations: Copy-paste evolution of wrapper metadata; defaults merged with overrides producing both keys.

Related errors


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