nikivdev/code · warning
AI returned unknown command '{}'.
Error message
AI returned unknown command '{}'. What it means
After tokenizing the suggestion, normalize_command lowercases tokens[1] and checks it against the set of valid subcommands (from clap's Cli). If the subcommand the AI produced is not a known subcommand or alias, the command would fail downstream, so it's rejected here with the full command in the message.
Source
Thrown at src/ask.rs:505
cmd = cmd.trim_start_matches("cmd:").trim().to_string();
} else if cmd.starts_with("command:") {
cmd = cmd.trim_start_matches("command:").trim().to_string();
}
if cmd.starts_with("flow ") {
cmd = format!("f {}", cmd.trim_start_matches("flow ").trim());
} else if !cmd.starts_with("f ") {
cmd = format!("f {}", cmd);
}
let tokens = shell_words::split(&cmd)
.unwrap_or_else(|_| cmd.split_whitespace().map(|s| s.to_string()).collect());
if tokens.len() < 2 {
bail!("Command '{}' is incomplete.", cmd);
}
let sub = tokens[1].to_ascii_lowercase();
if !valid_subcommands.contains(&sub) {
bail!("AI returned unknown command '{}'.", cmd);
}
Ok(cmd)
}
fn is_command_like(raw: &str, valid_subcommands: &HashSet<String>) -> bool {
let first = raw
.split_whitespace()
.next()
.unwrap_or("")
.trim()
.to_ascii_lowercase();
if first.is_empty() {
return false;
}
valid_subcommands.contains(&first)
}
View on GitHub (pinned to a747e741ae)
Solutions
- Compare the message's command against `f --help` output and correct the subcommand name manually
- Improve the prompt by injecting the exact current subcommand list and forbidding others
- Add fuzzy/alias matching in normalize_command (e.g. normalize_name-style comparison) before rejecting
- Fall back to re-asking the AI or presenting an interactive subcommand picker
Example fix
// before
let sub = tokens[1].to_ascii_lowercase();
if !valid_subcommands.contains(&sub) {
bail!("AI returned unknown command '{}'.", cmd);
}
// after
let sub = tokens[1].to_ascii_lowercase();
if !valid_subcommands.contains(&sub) {
if let Some(matched) = valid_subcommands.iter().find(|v| normalize_name(v) == normalize_name(&sub)) {
tokens[1] = matched.clone();
return Ok(tokens.join(" "));
}
bail!("AI returned unknown command '{}'. Valid subcommands: {:?}", cmd, valid_subcommands);
} Defensive patterns
Strategy: validation
Validate before calling
fn suggestion_subcommand_is_valid(raw: &str, valid: &HashSet<String>) -> bool {
let tokens: Vec<String> = raw.split_whitespace().map(|s| s.to_string()).collect();
tokens.get(1).map(|t| valid.contains(&t.to_ascii_lowercase())).unwrap_or(false)
} Try / catch
match normalize_command(raw, &valid_subcommands) {
Err(e) if e.to_string().contains("unknown command") => {
eprintln!("{}\nRun `f --help` for valid subcommands.", e);
}
other => other,
} Prevention
- Inject the exact current subcommand list into the AI prompt
- Keep CLI aliases registered so clap-derived valid_subcommands covers them
- Add fuzzy/normalized matching before rejecting near-miss names
- Re-validate suggestions whenever the CLI surface changes between versions
When it happens
Trigger: The AI hallucinates a subcommand ('f deploy-prod' when only 'deploy' exists), invents flags-as-subcommands, or uses a name from a different CLI version.
Common situations: Model trained on an older/newer CLI surface; task list vs CLI subcommand confusion; case-sensitivity handled but hyphen/underscore variants not in valid_subcommands; suggestion generated from stale help text.
Related errors
- No prompt provided. Usage: f agents run {} "your prompt here
- agent run requires a non-empty query
- prompt is empty
- archive message cannot be empty
- archive message must include at least one letter or number
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/0becb6d2f9c80075.
Report an issue: GitHub.