nikivdev/code · error
empty recipe selector
Error message
empty recipe selector
What it means
`select_recipe` rejects an empty (or whitespace-only) selector before doing any matching. This is a fast-fail input validation so callers get a precise message instead of a confusing 'no recipe matched' result.
Source
Thrown at src/recipe.rs:620
let mut hay = String::new();
hay.push_str(&r.id);
hay.push(' ');
hay.push_str(&r.name);
hay.push(' ');
hay.push_str(&r.description);
if !r.tags.is_empty() {
hay.push(' ');
hay.push_str(&r.tags.join(" "));
}
hay.to_ascii_lowercase().contains(&needle)
})
.collect()
}
fn select_recipe<'a>(recipes: &'a [Recipe], selector: &str) -> Result<&'a Recipe> {
let normalized = selector.trim();
if normalized.is_empty() {
bail!("empty recipe selector")
}
if let Some(recipe) = recipes.iter().find(|r| r.id == normalized) {
return Ok(recipe);
}
let lowered = normalized.to_ascii_lowercase();
let exact_name: Vec<&Recipe> = recipes
.iter()
.filter(|r| r.name.to_ascii_lowercase() == lowered)
.collect();
if exact_name.len() == 1 {
return Ok(exact_name[0]);
}
if exact_name.len() > 1 {
ambiguous_selector_error(selector, &exact_name)?;
bail!("ambiguous recipe selector")
}View on GitHub (pinned to a747e741ae)
Solutions
- Pass a non-empty recipe id on the command line
- In scripts, guard the variable: error out early if it is empty before invoking the tool
- List recipes first to pick a valid id
- Trim/validate user input before forwarding it as the selector
Example fix
# before
SEL=""; f recipe run "$SEL" # empty recipe selector
# after
[ -n "$SEL" ] || { echo "usage: run.sh <recipe-id>"; exit 2; }
f recipe run "$SEL" Defensive patterns
Strategy: validation
Validate before calling
// preflight: reject empty selector before invoking the CLI
fn require_selector(arg: Option<&str>) -> Result<String, String> {
arg.map(str::trim)
.filter(|s| !s.is_empty())
.map(str::to_string)
.ok_or_else(|| "recipe id required: pass a non-empty <recipe-id>".to_string())
} Type guard
fn has_selector(args: &[String]) -> bool {
args.get(1).map_or(false, |s| !s.trim().is_empty())
} Try / catch
match run() {
Err(e) if e.to_string().contains("empty recipe selector") => {
eprintln!("usage: f recipe run <recipe-id>");
std::process::exit(2);
}
other => other,
} Prevention
- Default-check shell variables before interpolation (`${SEL:?unset}` in bash)
- Always pass the selector as a positional argument, not via optional flags
- In wrappers, validate argv length before exec'ing the tool
- Trim user-supplied input before forwarding
When it happens
Trigger: Calling `run_recipe` with `RecipeRunOpts.selector` set to "" or only whitespace — typically an unset/empty shell variable or an argument accidentally dropped from the command line.
Common situations: Unset environment variable interpolated into the command (`f recipe run "$SEL"`); scripted invocation where an argument was conditional and omitted; piping a name with only spaces due to a parsing bug.
Related errors
- failed to select recipe
- no recipe matched '{}'
- Suggested command is incomplete.
- Command '{}' is incomplete.
- Relative path cannot be empty.
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/cf4b48561095ff32.
Report an issue: GitHub.