sigoden/aichat · error

Unknown command. Type ".help" for additional help.

Error message

Unknown command. Type ".help" for additional help.

What it means

`unknown_command()` is the catch-all handler for REPL commands that do not match any known command (including renamed/deprecated ones). It bails with a message directing the user to `.help` for the list of valid commands.

Solutions

  1. Run .help to list valid commands and correct the command name
  2. Check for renamed commands (e.g. .empty session replaced .clear messages)
  3. If the input was meant to be a chat message, do not prefix it with '.'

Example fix

// before: typo command
.conitnue
// after
.continue
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN: &[&str] = &[".help",".model",".agent",".starter",".edit",".continue",".regenerate",".copy",".empty",".save",".exit",".source",".last"];
fn is_known(cmd: &str) -> bool {
    let name = cmd.split_whitespace().next().unwrap_or("");
    KNOWN.contains(&name)
}

Type guard

fn is_dot_command(input: &str) -> bool {
    input.starts_with('.') && input.len() > 1
}

Try / catch

match repl(cmd) {
    Err(e) if e.to_string().contains("Unknown command") => {
        eprintln!("{} is not a command; run .help", cmd);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Typing any dot-command that is not in REPL_COMMANDS and not handled by an arm of the match in run_repl_command — e.g. misspellings like `.clr` or `.conitnue`, or commands removed in newer versions.

Common situations: Typos in command names; using commands from other CLI tools; referencing removed/renamed commands like .clear messages (which has its own message, but .clear alone hits this); copy-pasted command lists from outdated docs.

Related errors


AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09). Data as JSON: /api/errors/3a6fb85053b6f11b. Report an issue: GitHub.

Appendix: source

Thrown at src/repl/mod.rs:762

        .write()
        .after_chat_completion(&input, &output, &tool_results)?;
    if !tool_results.is_empty() {
        ask(
            config,
            abort_signal,
            input.merge_tool_results(output, tool_results),
            false,
        )
        .await
    } else {
        Config::maybe_autoname_session(config.clone());
        Config::maybe_compress_session(config.clone());
        Ok(())
    }
}

fn unknown_command() -> Result<()> {
    bail!(r#"Unknown command. Type ".help" for additional help."#);
}

fn dump_repl_help() {
    let head = REPL_COMMANDS
        .iter()
        .map(|cmd| format!("{:<24} {}", cmd.name, cmd.description))
        .collect::<Vec<String>>()
        .join("\n");
    println!(
        r###"{head}

Type ::: to start multi-line editing, type ::: to finish it.
Press Ctrl+O to open an editor for editing the input buffer.
Press Ctrl+C to cancel the response, Ctrl+D to exit the REPL."###,
    );
}

fn parse_command(line: &str) -> Option<(&str, Option<&str>)> {

View on GitHub (pinned to 82976d349a)