google-gemini/gemini-cli · warning
MAX_TURNS_EXCEEDED
MAX_TURNS_EXCEEDED
Error message
MAX_TURNS_EXCEEDED
What it means
MAX_TURNS_EXCEEDED here is the local (client-side) enforcement in the legacy agent loop. _runLoop increments turnCount each iteration and, when it exceeds config.getMaxSessionTurns() (and maxTurns>=0), calls _finishStream('max_turns', { code:'MAX_TURNS_EXCEEDED', maxTurns, turnCount }) and returns. This is the producer of the event that [242] translates.
Source
Thrown at packages/core/src/agent/legacy-agent-session.ts:187
} finally {
this._clearActiveStream();
}
}
private async _runLoop(
initialParts: Part[],
initialDisplayContent?: string,
): Promise<void> {
let currentParts: Part[] = initialParts;
let currentDisplayContent = initialDisplayContent;
let turnCount = 0;
const maxTurns = this._config.getMaxSessionTurns();
while (true) {
turnCount++;
if (maxTurns >= 0 && turnCount > maxTurns) {
this._finishStream('max_turns', {
code: 'MAX_TURNS_EXCEEDED',
maxTurns,
turnCount: turnCount - 1,
});
return;
}
const toolCallRequests: ToolCallRequestInfo[] = [];
let finishedReason: FinishReason | undefined = undefined;
const responseStream = this._client.sendMessageStream(
currentParts,
this._abortController.signal,
this._promptId,
undefined,
currentDisplayContent,
);
currentDisplayContent = undefined;
for await (const event of responseStream) {View on GitHub (pinned to 5024443c72)
Solutions
- Increase config.getMaxSessionTurns() / setMaxSessionTurns().
- Set maxTurns to -1 to disable the client-side cap (let server policy govern).
- Inspect tool_request/tool_response stream to find why turns accumulate and fix the failing tool.
Example fix
// before
getMaxSessionTurns() { return 20; }
// after
getMaxSessionTurns() { return 100; } Defensive patterns
Strategy: validation
Validate before calling
const max = config.getMaxSessionTurns(); if (max >= 0 && max < taskEstimatedTurns) config.setMaxSessionTurns(taskEstimatedTurns);
Type guard
function isMaxTurnsFinish(payload: unknown): payload is { code: 'MAX_TURNS_EXCEEDED'; maxTurns: number; turnCount: number } {
return typeof payload === 'object' && payload !== null && (payload as any).code === 'MAX_TURNS_EXCEEDED';
} Try / catch
// _finishStream is internal; callers react to the resulting agent_end event:
if (ev.type === 'agent_end' && ev.reason === 'max_turns' && isMaxTurnsFinish(ev.data)) { /* raise budget or refine task */ } Prevention
- Set maxTurns proportional to expected tool-call depth.
- Use maxTurns = -1 only when server-side policy is the real cap.
When it happens
Trigger: Each while(true) iteration in _runLoop: turnCount++; if (maxTurns>=0 && turnCount>maxTurns) -> _finishStream('max_turns', {...}); return. Triggered when a session runs longer than the configured budget.
Common situations: Default maxTurns is too low for the task; a tool returns errors so the loop never finishes; misconfigured getMaxSessionTurns returning a small number.
Related errors
- MAX_TURNS_EXCEEDED
- LOOP_DETECTED
- User requested to change authentication method
- User cancelled account validation
- AGENT_EXECUTION_BLOCKED
AI-assisted analysis of google-gemini/gemini-cli@5024443c72 (2026-08-12).
Data as JSON: /api/errors/78cfffe987a5b906.
Report an issue: GitHub.