sigoden/aichat · error

Unexpected call

Error message

Unexpected call: {function_name} {}

What it means

`extract_call_config_from_config` matches the function name against configured LLM functions; when the name isn't found in config and arguments aren't in an accepted shape, it bails with 'Unexpected call'. It means the invoked tool/function is not a recognized entry in the configuration.

Solutions

  1. Add the missing function definition to the config under the exact name the model called
  2. Correct the tool list exposed to the model so it matches configured functions
  3. Check for typos between the model's call and the config key

Example fix

// before: config lacks the function
[functions]
list_files = { command = "ls" }
// after
[functions]
list_files = { command = "ls" }
read_file = { command = "cat" }
Defensive patterns

Strategy: validation

Validate before calling

let configured: Vec<&str> = config.functions.keys().map(|s| s.as_str()).collect();
if !configured.contains(&call_name.as_str()) {
    eprintln!("function '{call_name}' is not in config: {configured:?}");
}

Try / catch

match tool_call.eval(&config) {
    Err(e) if e.to_string().starts_with("Unexpected call:") => {
        eprintln!("Unknown function requested by model; check [functions] config");
    }
    other => other?,
}

Prevention

When it happens

Trigger: A model calls a function name that has no matching entry in the `[functions]` config; called transitively by `eval` and `extract_call_config_from_agent`.

Common situations: Model hallucinates a tool name; user renamed/removed a function in config but the model's cached tool list still references the old name; typo in the function definition key.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/function.rs:243

                        vec![],
                        Default::default(),
                    ))
                }
            }
            None => self.extract_call_config_from_config(config),
        }
    }

    fn extract_call_config_from_config(&self, config: &GlobalConfig) -> Result<CallConfig> {
        let function_name = self.name.clone();
        match config.read().functions.contains(&function_name) {
            true => Ok((
                function_name.clone(),
                function_name,
                vec![],
                Default::default(),
            )),
            false => bail!("Unexpected call: {function_name} {}", self.arguments),
        }
    }
}

pub fn run_llm_function(
    cmd_name: String,
    cmd_args: Vec<String>,
    mut envs: HashMap<String, String>,
) -> Result<Option<String>> {
    let prompt = format!("Call {cmd_name} {}", cmd_args.join(" "));

    let mut bin_dirs: Vec<PathBuf> = vec![];
    if cmd_args.len() > 1 {
        let dir = Config::agent_functions_dir(&cmd_name).join("bin");
        if dir.exists() {
            bin_dirs.push(dir);
        }
    }

View on GitHub (pinned to 82976d349a)