{"record":{"id":"ab022b8cf27b3673","repo":"jdx/mise","slug":"semver-requires-exactly-1-argument","errorCode":null,"errorMessage":"semver requires exactly 1 argument","messagePattern":"semver requires exactly 1 argument","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"crates/aqua-registry/src/template.rs","lineNumber":334,"sourceCode":"    Ok(expr)\n}\n\nfn skip_whitespace(tokens: &mut std::iter::Peekable<std::slice::Iter<Token>>) {\n    while matches!(tokens.peek(), Some(Token::Whitespace(_))) {\n        tokens.next();\n    }\n}\n\n/// Function signature for template functions that return Value trait objects\ntype TemplateFn = fn(&[Box<dyn Value>]) -> Result<Box<dyn Value>>;\n\n/// Static registry of available template functions\nstatic FUNCTION_REGISTRY: LazyLock<HashMap<&'static str, TemplateFn>> = LazyLock::new(|| {\n    let mut registry: HashMap<&'static str, TemplateFn> = HashMap::new();\n\n    registry.insert(\"semver\", |args| {\n        if args.len() != 1 {\n            bail!(\"semver requires exactly 1 argument\");\n        }\n        let input = args[0].as_string();\n        let clean_version = input.strip_prefix('v').unwrap_or(&input);\n        let version = Versioning::new(clean_version)\n            .wrap_err_with(|| format!(\"invalid semver version: {input}\"))?;\n\n        Ok(Box::new(SemVerValue {\n            major: version.nth(0).unwrap_or(0),\n            minor: version.nth(1).unwrap_or(0),\n            patch: version.nth(2).unwrap_or(0),\n            original: clean_version.to_string(),\n        }) as Box<dyn Value>)\n    });\n\n    registry.insert(\"title\", |args| {\n        if args.len() != 1 {\n            bail!(\"title requires exactly 1 argument\");\n        }","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/crates/aqua-registry/src/template.rs#L316-L352","documentation":"command_wrapper options accept exactly four keys: content, executable, args, and env. Any other key is collected, sorted, and reported in this error (comma-joined), so the message may list several unknown keys at once.","triggerScenarios":"Options objects containing typo'd keys ('arg', 'envs', 'shell') or newer/misremembered option names; metadata written for a different tool's wrapper schema.","commonSituations":"Hand-authored mise command_wrapper metadata; schema drift between mise versions adding/renaming options.","solutions":["Remove or rename the listed keys to one of content, executable, args, env","Check the mise docs for the command_wrapper schema matching your mise version"],"exampleFix":"# before\n{\"command_wrapper\": [\"tool\", {\"executable\": \"bin/tool\", \"arg\": [\"--serve\"]}]}\n# after\n{\"command_wrapper\": [\"tool\", {\"executable\": \"bin/tool\", \"args\": [\"--serve\"]}]}","handlingStrategy":"validation","validationCode":"const ALLOWED: &[&str] = &[\"content\", \"executable\", \"args\", \"env\"];\nlet bad: Vec<_> = opts.keys().filter(|k| !ALLOWED.contains(&k.as_str())).collect();\nif !bad.is_empty() { /* reject or strip unknown keys before install */ }","typeGuard":"fn wrapper_options_are_supported(opts: &serde_json::Map<String, Value>) -> bool {\n    opts.keys().all(|k| matches!(k.as_str(), \"content\" | \"executable\" | \"args\" | \"env\"))\n}","tryCatchPattern":null,"preventionTips":["Copy command_wrapper examples from the mise docs for your version","Spell-check option keys; the error lists all offenders sorted"],"tags":["rust","mise","brew-cask","command-wrapper","unknown-option"],"backgroundTag":"unsupported-config-option","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}