sigoden/aichat · error
The request was aborted because an infinite loop of…
Error message
The request was aborted because an infinite loop of function calls was detected.
What it means
`eval_tool_calls` detects that after deduplicating the model's tool calls, no unique calls remain — the model keeps issuing the same call(s) repeatedly, which the library treats as an infinite function-call loop and aborts. This protects against runaway token spend and endless recursion.
Solutions
- Make the tool return meaningful, distinct results so the model stops repeating the call
- Improve the system prompt/tool descriptions so the model knows when to stop
- Check tool command exit/output handling in `run_llm_function` (a failing tool can cause retries)
- Cap loop iterations or dedup window in the agent config
Example fix
// before: tool always returns null
Ok(json!(null))
// after
Ok(json!({"status": "completed", "result": output})) Defensive patterns
Strategy: try-catch
Validate before calling
if ToolCall::dedup(calls.clone()).is_empty() {
return Err(anyhow!("tool calls already executed; aborting loop"));
} Try / catch
match agent.run().await {
Err(e) if e.to_string().contains("infinite loop of function calls") => {
eprintln!("Model looped on tool calls; refining prompt/tool output");
}
other => other?,
} Prevention
- Ensure tools return distinct, informative results
- Write tool descriptions that tell the model when to stop
- Add loop-iteration caps in your agent loop
When it happens
Trigger: `ToolCall::dedup(calls)` returns an empty vector because all requested tool calls were duplicates of previously executed ones; raised from `call_chat_completions`/`call_chat_completions_streaming` agent loops.
Common situations: An LLM keeps re-invoking the same tool with identical arguments because the tool result doesn't satisfy it; a tool returns no useful output so the model retries forever; misconfigured tool schemas cause the model to loop.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Exceed max_input_tokens limit
- The call ' ' has invalid arguments
- Unexpected call
- Tool call exit with
- No command generated
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/64f67ec855503eda.
Report an issue: GitHub.
Appendix: source
Thrown at src/function.rs:28
use std::{
collections::{HashMap, HashSet},
fs,
path::{Path, PathBuf},
};
#[cfg(windows)]
const PATH_SEP: &str = ";";
#[cfg(not(windows))]
const PATH_SEP: &str = ":";
pub fn eval_tool_calls(config: &GlobalConfig, mut calls: Vec<ToolCall>) -> Result<Vec<ToolResult>> {
let mut output = vec![];
if calls.is_empty() {
return Ok(output);
}
calls = ToolCall::dedup(calls);
if calls.is_empty() {
bail!("The request was aborted because an infinite loop of function calls was detected.")
}
let mut is_all_null = true;
for call in calls {
let mut result = call.eval(config)?;
if result.is_null() {
result = json!("DONE");
} else {
is_all_null = false;
}
output.push(ToolResult::new(call, result));
}
if is_all_null {
output = vec![];
}
Ok(output)
}
#[derive(Debug, Clone, Deserialize, Serialize)]View on GitHub (pinned to 82976d349a)