{"record":{"id":"44a89d100ed04c55","repo":"denisidoro/navi","slug":"no-command-captured-in-the-line","errorCode":null,"errorMessage":"No command captured in the line `{}`","messagePattern":"No command captured in the line `(.+?)`","errorType":"validation","errorClass":"anyhow","httpStatus":null,"severity":"error","filePath":"src/parser.rs","lineNumber":103,"sourceCode":"}\n\nfn parse_variable_line(line: &str) -> Result<(&str, &str, Option<FinderOpts>)> {\n    let caps = VAR_LINE_REGEX\n        .captures(line)\n        .ok_or_else(|| anyhow!(\"No variables, command, and options found in the line `{}`\", line))?;\n    let variable = caps\n        .get(1)\n        .ok_or_else(|| anyhow!(\"No variable captured in the line `{}`\", line))?\n        .as_str()\n        .trim();\n    let mut command_plus_opts = caps\n        .get(2)\n        .ok_or_else(|| anyhow!(\"No command and options captured in the line `{}`\", line))?\n        .as_str()\n        .split(\"---\");\n    let command = command_plus_opts\n        .next()\n        .ok_or_else(|| anyhow!(\"No command captured in the line `{}`\", line))?;\n    let command_options = command_plus_opts.next().map(parse_opts).transpose()?;\n    Ok((variable, command, command_options))\n}\n\nfn without_prefix(line: &str) -> String {\n    // The prefix character (#, %, @) is always 1-byte ASCII.\n    // Skip it and let trim() handle any whitespace separator, including\n    // multi-byte whitespace like non-breaking space (\\u{a0}).\n    line.get(1..).unwrap_or(\"\").trim().to_string()\n}\n\n#[derive(Clone, Default)]\npub struct FilterOpts {\n    pub allowlist: Vec<String>,\n    pub denylist: Vec<String>,\n    pub hash: Option<u64>,\n}\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/denisidoro/navi/blob/f7330b9ad5bd95b7d1a3c96d00e0a77deb589147/src/parser.rs#L85-L121","documentation":"Thrown by `parse_variable_line` in src/parser.rs when the command-and-options capture (group 2) exists but splitting it on `---` yields no first element (the command). Practically defensive — `split` always yields a first item — this fires when the command part is empty.","triggerScenarios":"A line like `#my-var: --- --header \"x\"` where the text before `---` is empty, so the command portion is missing while options are present.","commonSituations":"Writing options-only lines assuming a default command; deleting the command but keeping the `---` options tail; template files with the command left as a placeholder to fill in.","solutions":["Add a command before the `---` separator, e.g. `#my-var: ls --- --header \"Files\"`","Remove the empty variable line if there is no command to run","Fill in command placeholders left in template/config files"],"exampleFix":"// before\n#my-var: --- --header \"Files\"\n// after\n#my-var: ls --- --header \"Files\"","handlingStrategy":"validation","validationCode":"let has_cmd_before_opts = |line: &str| {\n    line.split_once(':').and_then(|(_, rhs)| rhs.split_once(\"---\"))\n        .map_or(false, |(cmd, _)| !cmd.trim().is_empty())\n};\n// require has_cmd_before_opts(line) before parsing","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Place the command before the `---` separator — options alone are invalid","Fill in placeholder commands left in templates before running","Grep config for `: ---` patterns to catch empty-command lines early"],"tags":["parsing","config","command"],"backgroundTag":"missing-command","analyzedSha":"f7330b9ad5bd95b7d1a3c96d00e0a77deb589147","analyzedAt":"2026-09-03T13:58:22.429Z","contentChangedAt":"2026-09-03T13:58:22.429Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}