paperclipai/paperclip · error

agent turn limit exceeded

Error message

agent turn limit exceeded

What it means

runEvalSessionCli enforces per-run budget limits after the provider turn completes. It computes usage from the turn snapshot via evalSessionUsage and throws when the agent consumed more agent turns than request.limits.maxAgentTurns allows. This is an intentional fail-fast guard so an eval session cannot exceed its resource budget.

Source

Thrown at packages/paperclip-runner/src/cli/eval-session.ts:243

): EvalSessionUsage | null {
  if (!snapshot?.usageLedger?.length) return null;
  try {
    return evalSessionUsage(request.model, snapshot);
  } catch {
    return null;
  }
}

export function boundedEvalSessionUsage(
  request: EvalSessionRequest,
  turn: CapabilityLiveTurnResult,
): EvalSessionUsage | null {
  if (turn.status !== "completed") {
    return usageIfAvailable(request, turn.snapshot);
  }
  const usage = evalSessionUsage(request.model, turn.snapshot);
  if (usage.agentTurns > request.limits.maxAgentTurns) {
    throw new Error("agent turn limit exceeded");
  }
  if (
    usage.estimatedCostNanodollars >
    request.limits.maxEstimatedCostNanodollars
  ) {
    throw new Error("estimated cost limit exceeded");
  }
  if (
    usage.providerReportedCostNanodollars >
    request.limits.maxEstimatedCostNanodollars
  ) {
    throw new Error("provider-reported cost limit exceeded");
  }
  return usage;
}

async function closeSession(
  session: CapabilityLiveSession | null,

View on GitHub (pinned to 01ad858492)

Solutions

  1. Raise request.limits.maxAgentTurns in the eval request to a value appropriate for the task
  2. Shorten or simplify the prompt so fewer agentic turns are needed
  3. Switch to a model/provider that completes the task in fewer turns
  4. Inspect the turn snapshot to confirm the turn count is real and not caused by an internal retry loop

Example fix

// before
limits: { maxAgentTurns: 5, ... }
// after
limits: { maxAgentTurns: 20, ... }
Defensive patterns

Strategy: validation

Validate before calling

import { evalSessionUsage } from "./eval-session-usage.js";
const projectedTurns = 1 + Math.ceil(request.prompt.length / 2000); // rough pre-flight floor
if (projectedTurns >= request.limits.maxAgentTurns) {
  throw new Error(`maxAgentTurns=${request.limits.maxAgentTurns} too low for this task; raise the limit before running`);
}
// after the turn, before it throws:
const usage = evalSessionUsage(request.model, turn.snapshot);
if (usage.agentTurns > request.limits.maxAgentTurns) {
  console.warn(`agent turns ${usage.agentTurns} exceed limit ${request.limits.maxAgentTurns}; raising limit or simplifying task`);
}

Try / catch

try {
  await runEvalSessionCli(request, cli);
} catch (error) {
  if (error instanceof Error && error.message === "agent turn limit exceeded") {
    request.limits.maxAgentTurns = Math.ceil(request.limits.maxAgentTurns * 2);
    return runEvalSessionCli(request, cli);
  }
  throw error;
}

Prevention

When it happens

Trigger: A completed provider turn's snapshot reports usage.agentTurns > request.limits.maxAgentTurns in runEvalSessionCli — e.g. a task/prompt that required more agentic iterations (tool calls, retries, multi-step reasoning) than the configured cap.

Common situations: Eval harness configured with too low maxAgentTurns for the task complexity; prompts that force many tool-use round trips; a provider/model that loops or re-tries internally, inflating turn counts; limits copied from a simpler benchmark.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/3b9e523fc5f88f10. Report an issue: GitHub.