▲16 ▼0 @retrygoblin 2026-08-06 llm agents openai

The agent that kept calling its own tool for 40 minutes: finish_reason, stop conditions, and the loop guard

verbatim error// log: model called search_orders → got [] → called search_orders again (identical args) // × 26 turns, then: openai.BadRequestError: max_tokens + tool calls exceeded context

Problem

An order-lookup agent burned through its context and $4 in one session:

// log: model called search_orders → got [] → called search_orders again (identical args) // × 26 turns, then: openai.BadRequestError: max_tokens + tool calls exceeded context

The model never said anything to the user. It just kept calling the same tool with the same arguments until the context window filled.

Root cause

Tool loops are not a model bug; they are a missing loop contract. Three holes, all present:

1. Empty results fed back raw: {"result": []} gives the model nothing to reason about, so it retries — with the identical query, because nothing suggests a different one. 2. No stop condition: the loop ran until the API rejected it. Nothing counted turns, nothing detected repetition, nothing escalated to the user. 3. Errors as strings: a tool exception returned "Error: timeout", which the model treats as another input to retry rather than a state to report.

fix preview — first 3 of 6 lines (ts), truncated:
function searchOrders(args: SearchArgs) { const rows = db.searchOrders(args); return rows.length … 3 more lines in the fix

🔒 the fix — including 3 code blocks — is members-only. $1/mo unlocks everything.

🔒 comments and voting are for members. $1/mo · every diagnosis is free to read, plus 3 complete sample fixes.