denisidoro/navi · error · anyhow

No command captured in the line `{}`

Error message

No command captured in the line `{}`

What it means

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.

Source

Thrown at src/parser.rs:103

}

fn parse_variable_line(line: &str) -> Result<(&str, &str, Option<FinderOpts>)> {
    let caps = VAR_LINE_REGEX
        .captures(line)
        .ok_or_else(|| anyhow!("No variables, command, and options found in the line `{}`", line))?;
    let variable = caps
        .get(1)
        .ok_or_else(|| anyhow!("No variable captured in the line `{}`", line))?
        .as_str()
        .trim();
    let mut command_plus_opts = caps
        .get(2)
        .ok_or_else(|| anyhow!("No command and options captured in the line `{}`", line))?
        .as_str()
        .split("---");
    let command = command_plus_opts
        .next()
        .ok_or_else(|| anyhow!("No command captured in the line `{}`", line))?;
    let command_options = command_plus_opts.next().map(parse_opts).transpose()?;
    Ok((variable, command, command_options))
}

fn without_prefix(line: &str) -> String {
    // The prefix character (#, %, @) is always 1-byte ASCII.
    // Skip it and let trim() handle any whitespace separator, including
    // multi-byte whitespace like non-breaking space (\u{a0}).
    line.get(1..).unwrap_or("").trim().to_string()
}

#[derive(Clone, Default)]
pub struct FilterOpts {
    pub allowlist: Vec<String>,
    pub denylist: Vec<String>,
    pub hash: Option<u64>,
}

View on GitHub (pinned to f7330b9ad5)

Solutions

  1. Add a command before the `---` separator, e.g. `#my-var: ls --- --header "Files"`
  2. Remove the empty variable line if there is no command to run
  3. Fill in command placeholders left in template/config files

Example fix

// before
#my-var: --- --header "Files"
// after
#my-var: ls --- --header "Files"
Defensive patterns

Strategy: validation

Validate before calling

let has_cmd_before_opts = |line: &str| {
    line.split_once(':').and_then(|(_, rhs)| rhs.split_once("---"))
        .map_or(false, |(cmd, _)| !cmd.trim().is_empty())
};
// require has_cmd_before_opts(line) before parsing

Prevention

When it happens

Trigger: A line like `#my-var: --- --header "x"` where the text before `---` is empty, so the command portion is missing while options are present.

Common situations: 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.

Related errors


AI-assisted analysis of denisidoro/navi@f7330b9ad5 (2026-09-03). Data as JSON: /api/errors/44a89d100ed04c55. Report an issue: GitHub.