{"record":{"id":"c43b0726f70ef405","repo":"nikivdev/code","slug":"no-recipe-matched","errorCode":null,"errorMessage":"no recipe matched '{}'","messagePattern":"no recipe matched '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/recipe.rs","lineNumber":651,"sourceCode":"        return Ok(exact_name[0]);\n    }\n    if exact_name.len() > 1 {\n        ambiguous_selector_error(selector, &exact_name)?;\n        bail!(\"ambiguous recipe selector\")\n    }\n\n    let contains: Vec<&Recipe> = recipes\n        .iter()\n        .filter(|r| {\n            r.id.to_ascii_lowercase().contains(&lowered)\n                || r.name.to_ascii_lowercase().contains(&lowered)\n        })\n        .collect();\n    if contains.len() == 1 {\n        return Ok(contains[0]);\n    }\n    if contains.is_empty() {\n        bail!(\"no recipe matched '{}'\", selector);\n    }\n    ambiguous_selector_error(selector, &contains)?;\n    bail!(\"ambiguous recipe selector\")\n}\n\nfn ambiguous_selector_error(selector: &str, matches: &[&Recipe]) -> Result<()> {\n    eprintln!(\"recipe selector '{}' matched multiple recipes:\", selector);\n    for recipe in matches {\n        eprintln!(\"  - {} ({})\", recipe.id, recipe.name);\n    }\n    Ok(())\n}\n\nfn resolve_cwd(cwd: Option<&str>) -> Result<PathBuf> {\n    if let Some(cwd) = cwd {\n        return Ok(expand_tilde(cwd));\n    }\n    detect_project_root()","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/recipe.rs#L633-L669","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run the recipe list command and copy the exact id","Check for typos in the selector and retry with a correct id","Verify the recipe file exists in the configured (global/project) recipe directory and scope","Load a different scope (e.g. --global) if the recipe lives elsewhere"],"exampleFix":"// before\n$ f recipe run lnt\nno recipe matched 'lnt'\n// after\n$ f recipe list   # shows id `lint-all`\n$ f recipe run lint-all","handlingStrategy":"validation","validationCode":"// preflight: verify the selector exists before invoking\nfn known<'a>(recipes: &'a [Recipe], id: &str) -> Option<&'a Recipe> {\n    recipes.iter().find(|r| r.id == id.trim())\n}\n// if known(...).is_none() { eprintln!(\"unknown recipe; run the list command\"); }","typeGuard":"fn selector_exists(recipes: &[Recipe], sel: &str) -> bool {\n    let t = sel.trim();\n    recipes.iter().any(|r| r.id == t)\n}","tryCatchPattern":"match run_recipe(opts) {\n    Err(e) if e.to_string().starts_with(\"no recipe matched\") => {\n        eprintln!(\"unknown recipe id; run the list command and retry with an exact id\");\n        std::process::exit(2);\n    }\n    other => other,\n}","preventionTips":["Copy recipe ids from the list command instead of typing from memory","Check the recipe file exists in the active scope/directory before running","Update scripts after renaming or deleting recipes","Remember matching is case-insensitive substring fallback — prefer exact ids"],"tags":["no-match","recipe-selector","cli","input-validation"],"backgroundTag":"recipe-not-found","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}