{"record":{"id":"9d6a323a19850623","repo":"xtekky/gpt4free","slug":"tool-loop-detected-request-contains-total-tool-c","errorCode":null,"errorMessage":"Tool loop detected: request contains {total_tool_calls} tool calls (limit {GLOBAL_TOOL_CALL_LIMIT}). The assistant is stuck calling tools repeatedly. Stop calling tools and answer directly, or switch strategy (e.g. use read_file with an absolute path instead of search).","messagePattern":"Tool loop detected: request contains (.+?) tool calls \\(limit (.+?)\\)\\. The assistant is stuck calling tools repeatedly\\. Stop calling tools and answer directly, or switch strategy \\(e\\.g\\. use read_file with an absolute path instead of search\\)\\.","errorType":"exception","errorClass":"ToolLoopError","httpStatus":null,"severity":"error","filePath":"g4f/api/tool_loop_detection.py","lineNumber":171,"sourceCode":"        role = message.get(\"role\")\n\n        # Assistant message may carry tool_calls.\n        if role == \"assistant\":\n            tool_calls = message.get(\"tool_calls\") or []\n            if isinstance(tool_calls, list):\n                for tc in tool_calls:\n                    key = _tool_call_key(tc)\n                    if key is None:\n                        continue\n                    total_tool_calls += 1\n                    call_counts[key] = call_counts.get(key, 0) + 1\n                    tc_id = tc.get(\"id\") if isinstance(tc, dict) else None\n                    if tc_id:\n                        pending_calls[tc_id] = key\n\n                    # Hard global cap.\n                    if total_tool_calls > GLOBAL_TOOL_CALL_LIMIT:\n                        raise ToolLoopError(\n                            f\"Tool loop detected: request contains {total_tool_calls} \"\n                            f\"tool calls (limit {GLOBAL_TOOL_CALL_LIMIT}). The assistant \"\n                            f\"is stuck calling tools repeatedly. Stop calling tools and \"\n                            f\"answer directly, or switch strategy (e.g. use read_file \"\n                            f\"with an absolute path instead of search).\",\n                            function_name=key[0],\n                            arguments=key[1],\n                            repeats=total_tool_calls,\n                        )\n\n                    # Per-query repeat cap.\n                    if call_counts[key] > MAX_REPEATS_PER_QUERY:\n                        raise ToolLoopError(\n                            f\"Tool loop detected: function '{key[0]}' was called \"\n                            f\"{call_counts[key]} times with identical arguments \"\n                            f\"({call_counts[key] - 1} retries, limit is \"\n                            f\"{MAX_REPEATS_PER_QUERY - 1}). Stop repeating this call. \"\n                            f\"Arguments: {key[1]}\",","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/api/tool_loop_detection.py#L153-L189","documentation":"Error \"Tool loop detected: request contains {total_tool_calls} tool calls (limit {GLOBAL_TOOL_CALL_LIMIT}). The assistant is stuck calling tools repeatedly. Stop calling tools and answer directly, or switch strategy (e.g. use read_file with an absolute path instead of search).\" thrown in xtekky/gpt4free.","triggerScenarios":"Thrown at g4f/api/tool_loop_detection.py:171 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Stop issuing tool calls and answer the user directly.","Change strategy, e.g. use read_file with an absolute path instead of repeated searches."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}