{"record":{"id":"1ac7eab4c12de95e","repo":"jdx/mise","slug":"an-exec-entry-with-no-command","errorCode":null,"errorMessage":"an exec entry with no command","messagePattern":"an exec entry with no command","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/packslip.rs","lineNumber":1358,"sourceCode":"        .list_current_installed_versions(config)\n        .into_iter()\n        .find(|(b, _)| b.ba().short == name || b.tool_name() == name || b.id() == name);\n    match by_name {\n        Some(found) => Ok(found),\n        None => bail!(\"{name} is not an active, installed tool or one of their executables\"),\n    }\n}\n\n/// Run one of the tool's own executables and return what it printed.\nasync fn run_tool(\n    config: &Arc<Config>,\n    backend: &Arc<dyn Backend>,\n    tv: &ToolVersion,\n    argv: &[String],\n    env: &BTreeMap<String, String>,\n) -> Result<String> {\n    let Some((program, args)) = argv.split_first() else {\n        bail!(\"an exec entry with no command\");\n    };\n    let Some(path) = backend.which(config, tv, program).await? else {\n        bail!(\"{} has no executable called {program}\", tv.style());\n    };\n    run_resource_command(\n        &path,\n        args,\n        env,\n        &tv.install_path(),\n        std::time::Duration::from_secs(5),\n    )\n    .await\n}\n\n/// Run vendor resource generation outside the user's project, without\n/// input, under a deadline. Empty output is a failed source, never a cache hit.\nasync fn run_resource_command(\n    path: &Path,","sourceCodeStart":1340,"sourceCodeEnd":1376,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/packslip.rs#L1340-L1376","documentation":"run_tool executes an entry from the tool's own exec/completion config. The argv is expected to have at least a program; when the entry is an empty array (or has no elements), split_first returns None and this error is raised.","triggerScenarios":"A packslip's exec/completion resource entry is an empty list, e.g. exec = [] or a command field that resolves to nothing after parsing.","commonSituations":"Hand-written packslip with an empty exec array, templating/substitution that evaluated to nothing, an optional command field left blank.","solutions":["Provide a command in the exec entry, e.g. exec = [\"tool\", \"--help\"] or [\"tool\", \"completions\"]","Check templated values so the command does not expand to empty","Fix the packslip entry so argv has at least one element"],"exampleFix":"// before (packslip)\n// exec = []\n// after\n// exec = [\"mytool\", \"completions\"]","handlingStrategy":"validation","validationCode":"if (!Array.isArray(exec) || exec.length === 0) throw new Error('exec entry needs at least a command');","typeGuard":"const hasCommand = (argv: unknown): argv is [string, ...string[]] => Array.isArray(argv) && argv.length > 0 && typeof argv[0] === 'string';","tryCatchPattern":"try { await runTool(...) } catch (e) { if (/an exec entry with no command/.test(e.message)) { fixPackslipExec(); } else { throw e; } }","preventionTips":["Always include at least the program name in exec entries","Check templating so commands don't expand to empty","Lint packslip exec arrays before publishing"],"tags":["packslip","config","exec","validation"],"backgroundTag":"empty-required-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}