denisidoro/navi · error · anyhow

Given options are missing a closing quote

Error message

Given options are missing a closing quote

What it means

Thrown by `parse_opts` in src/parser.rs when `shellwords::split(text)` fails, which happens when the finder options string contains an unterminated quote. The library treats the whole options text as shell-like words, so unbalanced quoting is unrecoverable.

Source

Thrown at src/parser.rs:19

use crate::common::fs;
use crate::deser;
use crate::finder::structures::{Opts as FinderOpts, SuggestionType};
use crate::prelude::*;
use crate::structures::cheat::VariableMap;
use crate::structures::item::Item;
use std::io::Write;

lazy_static! {
    pub static ref VAR_LINE_REGEX: Regex = Regex::new(r"^\$\s*([^:]+):(.*)").expect("Invalid regex");
}

fn parse_opts(text: &str) -> Result<FinderOpts> {
    let mut multi = false;
    let mut prevent_extra = false;

    let mut opts = FinderOpts::var_default();

    let parts = shellwords::split(text).map_err(|_| anyhow!("Given options are missing a closing quote"))?;

    parts
        .into_iter()
        .filter(|part| {
            // We'll take parts in pairs of 2: (argument, value). Flags don't have a value tho, so we filter and handle them beforehand.
            match part.as_str() {
                "--multi" => {
                    multi = true;
                    false
                }
                "--prevent-extra" => {
                    prevent_extra = true;
                    false
                }
                "--expand" => {
                    opts.map = Some(format!("{} fn map::expand", fs::exe_string()));
                    false
                }

View on GitHub (pinned to f7330b9ad5)

Solutions

  1. Add the missing closing quote to the options string in the config/snippet line
  2. Remove quotes entirely if the option value contains no spaces
  3. Replace smart quotes (“ ” ‘ ’) with plain ASCII quotes
  4. Test the options string in a real shell first; if the shell rejects it, the parser will too

Example fix

// before (config line)
my-var: cat file.txt --- --header "my title
// after
my-var: cat file.txt --- --header "my title"
Defensive patterns

Strategy: validation

Validate before calling

fn quotes_balanced(s: &str) -> bool {
    let mut n = 0;
    for c in s.chars() {
        if c == '"' || c == '\'' { n += 1; }
    }
    n % 2 == 0
}
// check quotes_balanced(options_text) before feeding it to the parser

Prevention

When it happens

Trigger: A snippet/config line's options section after `---` contains a quote character that is opened but never closed, e.g. `--- --header "my title` or `--fzf-overrides '--preview 'foo'` with mismatched quotes.

Common situations: Hand-writing fzf overrides in a config file with nested quotes; copy-pasting shell commands with smart/curly quotes; editing snippet definitions and deleting a closing quote.

Related errors


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