nikivdev/code · error

no recipe matched '{}'

Error message

no recipe matched '{}'

What it means

Final fallback in `select_recipe`: after exact id and exact name both fail, it does a case-insensitive substring match on id and name. Zero matches produces this message naming the selector; more than one produces the ambiguity error instead.

Source

Thrown at src/recipe.rs:651

        return Ok(exact_name[0]);
    }
    if exact_name.len() > 1 {
        ambiguous_selector_error(selector, &exact_name)?;
        bail!("ambiguous recipe selector")
    }

    let contains: Vec<&Recipe> = recipes
        .iter()
        .filter(|r| {
            r.id.to_ascii_lowercase().contains(&lowered)
                || r.name.to_ascii_lowercase().contains(&lowered)
        })
        .collect();
    if contains.len() == 1 {
        return Ok(contains[0]);
    }
    if contains.is_empty() {
        bail!("no recipe matched '{}'", selector);
    }
    ambiguous_selector_error(selector, &contains)?;
    bail!("ambiguous recipe selector")
}

fn ambiguous_selector_error(selector: &str, matches: &[&Recipe]) -> Result<()> {
    eprintln!("recipe selector '{}' matched multiple recipes:", selector);
    for recipe in matches {
        eprintln!("  - {} ({})", recipe.id, recipe.name);
    }
    Ok(())
}

fn resolve_cwd(cwd: Option<&str>) -> Result<PathBuf> {
    if let Some(cwd) = cwd {
        return Ok(expand_tilde(cwd));
    }
    detect_project_root()

View on GitHub (pinned to a747e741ae)

Solutions

  1. Run the recipe list command and copy the exact id
  2. Check for typos in the selector and retry with a correct id
  3. Verify the recipe file exists in the configured (global/project) recipe directory and scope
  4. Load a different scope (e.g. --global) if the recipe lives elsewhere

Example fix

// before
$ f recipe run lnt
no recipe matched 'lnt'
// after
$ f recipe list   # shows id `lint-all`
$ f recipe run lint-all
Defensive patterns

Strategy: validation

Validate before calling

// preflight: verify the selector exists before invoking
fn known<'a>(recipes: &'a [Recipe], id: &str) -> Option<&'a Recipe> {
    recipes.iter().find(|r| r.id == id.trim())
}
// if known(...).is_none() { eprintln!("unknown recipe; run the list command"); }

Type guard

fn selector_exists(recipes: &[Recipe], sel: &str) -> bool {
    let t = sel.trim();
    recipes.iter().any(|r| r.id == t)
}

Try / catch

match run_recipe(opts) {
    Err(e) if e.to_string().starts_with("no recipe matched") => {
        eprintln!("unknown recipe id; run the list command and retry with an exact id");
        std::process::exit(2);
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling `run_recipe` with a selector string that is neither an id, an exact name, nor a unique substring of any loaded recipe's id/name — a typo, a recipe not present in the current scope, or a substring matching nothing.

Common situations: Misspelling a recipe id; running before recipes from the expected directory/scope are installed; case/whitespace differences that don't overlap as substring; referencing a recipe that was renamed or deleted.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/c43b0726f70ef405. Report an issue: GitHub.