sigoden/aichat · error · anyhow::Error

The call ' ' has invalid arguments

Error message

The call '{call_name}' has invalid arguments: {arguments}

What it means

During function/tool-call evaluation, the arguments field must be a JSON object or a JSON-encoded string of an object. If it's a string that fails to parse as JSON, or any other JSON type, evaluation aborts with this error naming the call and the offending arguments.

Solutions

  1. Inspect the raw arguments string and fix the JSON (quotes, trailing commas)
  2. Have the model retry the tool call, or re-prompt with stricter JSON instructions
  3. Pre-validate/sanitize argument strings with serde_json::from_str before eval

Example fix

// before: arguments = "{ 'path': '/tmp' }" (invalid JSON)
// after: arguments = "{ \"path\": \"/tmp\" }"
Defensive patterns

Strategy: validation

Validate before calling

fn valid_args(args: &serde_json::Value) -> bool {
    args.is_object()
        || args.as_str().map(|s| serde_json::from_str::<serde_json::Value>(s).map(|v| v.is_object()).unwrap_or(false)).unwrap_or(false)
}

Type guard

fn as_object_args(args: &serde_json::Value) -> Option<serde_json::Value> {
    match args {
        v if v.is_object() => Some(v.clone()),
        serde_json::Value::String(s) => serde_json::from_str(s).ok().filter(|v| v.is_object()),
        _ => None,
    }
}

Try / catch

match eval_function(&f) {
    Err(e) if e.to_string().contains("has invalid arguments") => {
        // re-prompt the model / retry with strict JSON schema
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling Function::eval where self.arguments is a non-JSON string (e.g. Python-dict-style text with single quotes) or a scalar/array instead of an object.

Common situations: LLM emits malformed JSON arguments in a tool call; single-quoted or trailing-comma JSON from the model; arguments serialized as a plain string without JSON encoding.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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

Appendix: source

Thrown at src/function.rs:183

    pub fn new(name: String, arguments: Value, id: Option<String>) -> Self {
        Self {
            name,
            arguments,
            id,
        }
    }

    pub fn eval(&self, config: &GlobalConfig) -> Result<Value> {
        let (call_name, cmd_name, mut cmd_args, envs) = match &config.read().agent {
            Some(agent) => self.extract_call_config_from_agent(config, agent)?,
            None => self.extract_call_config_from_config(config)?,
        };

        let json_data = if self.arguments.is_object() {
            self.arguments.clone()
        } else if let Some(arguments) = self.arguments.as_str() {
            let arguments: Value = serde_json::from_str(arguments).map_err(|_| {
                anyhow!("The call '{call_name}' has invalid arguments: {arguments}")
            })?;
            arguments
        } else {
            bail!(
                "The call '{call_name}' has invalid arguments: {}",
                self.arguments
            );
        };

        cmd_args.push(json_data.to_string());

        let output = match run_llm_function(cmd_name, cmd_args, envs)? {
            Some(contents) => serde_json::from_str(&contents)
                .ok()
                .unwrap_or_else(|| json!({"output": contents})),
            None => Value::Null,
        };

View on GitHub (pinned to 82976d349a)