{"record":{"id":"9abea603bed8ce97","repo":"PrefectHQ/fastmcp","slug":"tool-call-limit-exceeded-at-most-max-tool-calls","errorCode":null,"errorMessage":"Tool call limit exceeded: at most {max_tool_calls} call_tool() invocations are allowed per execute().","messagePattern":"Tool call limit exceeded: at most (.+?) call_tool\\(\\) invocations are allowed per execute\\(\\)\\.","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/experimental/transforms/code_mode.py","lineNumber":613,"sourceCode":"                str,\n                Field(\n                    description=(\n                        \"Python async code to execute tool calls via call_tool(name, arguments)\"\n                    )\n                ),\n            ],\n            ctx: Context = None,  # type: ignore[assignment]  # ty:ignore[invalid-parameter-default]\n        ) -> Any:\n            \"\"\"Execute tool calls using Python code.\"\"\"\n\n            call_count = 0\n\n            async def call_tool(tool_name: str, params: dict[str, Any]) -> Any:\n                nonlocal call_count\n                if max_tool_calls is not None:\n                    call_count += 1\n                    if call_count > max_tool_calls:\n                        raise ToolError(\n                            f\"Tool call limit exceeded: at most {max_tool_calls} \"\n                            \"call_tool() invocations are allowed per execute().\"\n                        )\n\n                backend_tools = await transform.get_tool_catalog(ctx)\n                tool = transform._find_tool(tool_name, backend_tools)\n                if tool is None:\n                    raise NotFoundError(f\"Unknown tool: {tool_name}\")\n\n                result = await ctx.fastmcp.call_tool(tool.name, params)\n                return _unwrap_tool_result(result)\n\n            return await transform.sandbox_provider.run(\n                code,\n                external_functions={\"call_tool\": call_tool},\n            )\n\n        return Tool.from_function(","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/experimental/transforms/code_mode.py#L595-L631","documentation":"The CodeMode execute tool wraps sandboxed code's call_tool() with a per-execute budget (max_tool_calls). Each invocation increments a counter; once it exceeds the limit a ToolError is raised, protecting the server from runaway generated code.","triggerScenarios":"Generated code inside the sandbox calls call_tool() more than max_tool_calls times during a single execute() — e.g. unbounded loops iterating a tool per item, or retry logic that keeps calling tools.","commonSituations":"LLM-generated code with while/for loops calling tools repeatedly; processing large datasets one call at a time; misconfigured (too low) max_tool_calls for legitimate workloads.","solutions":["Raise max_tool_calls when constructing CodeModeTransform to accommodate legitimate workloads","Set max_tool_calls=None to disable the limit (only if generated code is trusted)","Refactor the calling code to batch work into fewer tool calls","Handle ToolError in the caller and instruct the model to reduce tool usage"],"exampleFix":"// before\ntransform = CodeModeTransform(max_tool_calls=5)  # loop calls tool 50x\n\n// after\ntransform = CodeModeTransform(max_tool_calls=100)  # or batch the loop into one call","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = await transform.execute(code)\nexcept ToolError as e:\n    if \"Tool call limit exceeded\" in str(e):\n        # raise max_tool_calls or reduce tool usage in generated code\n        ...\n    raise","preventionTips":["Size max_tool_calls to your workload, or set it to None for trusted code","Prompt the model to batch tool operations instead of per-item calls","Instrument generated code to count call_tool() invocations before hitting the cap"],"tags":["code-mode","rate-limit","tool-error","fastmcp"],"backgroundTag":"tool-call-limit-exceeded","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}