langchain-ai/deepagents · error · RuntimeError

agent hit tool approval interrupt limit

Error message

agent hit tool approval interrupt limit

What it means

_invoke_until_unblocked repeatedly resumes the graph after tool-approval interrupts, up to a fixed maximum number of iterations. When the agent keeps returning approval interrupts beyond that limit, this RuntimeError is raised to stop an infinite approve/resume cycle.

Source

Thrown at libs/talon/deepagents_talon/runtime.py:436

        if not callable(ainvoke):
            msg = "Deep Agents graph does not expose async invocation"
            raise TypeError(msg)
        return cast("Callable[..., Awaitable[object]]", ainvoke)

    async def _invoke_until_unblocked(
        self,
        content: ModelContent,
        request: AgentRequest,
    ) -> object:
        state = await self._invoke_with_retries(content, request.conversation_id)
        for _ in range(DEFAULT_MAX_APPROVAL_ROUNDS):
            interrupts = _interrupts_from_state(state)
            if not interrupts:
                return state
            resume = await self._build_approval_resume(request, interrupts)
            state = await self._resume_with_retries(resume, request.conversation_id)
        msg = "agent hit tool approval interrupt limit"
        raise RuntimeError(msg)

    async def _build_approval_resume(
        self,
        request: AgentRequest,
        interrupts: Sequence[object],
    ) -> Command:
        payload: dict[str, dict[str, list[dict[str, str]]]] = {}
        for interrupt in interrupts:
            interrupt_id = _interrupt_id(interrupt)
            if interrupt_id is None:
                logger.warning("Received tool approval interrupt without an id")
                continue
            action_requests = _action_requests_from_interrupt(interrupt)
            decision, reject_message, _resolution = await _approval_decision(
                request,
                interrupt_id,
                action_requests,
            )

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Increase the runtime's approval-interrupt limit if long approval chains are legitimate
  2. Fix the approval handler/_build_approval_resume wiring so a resume actually satisfies the pending interrupts
  3. Adjust the agent prompt/tools so it stops re-requesting approval for rejected actions
Defensive patterns

Strategy: try-catch

Try / catch

try:
    reply = await runtime.invoke(request)
except RuntimeError as exc:
    if "tool approval interrupt limit" in str(exc):
        # surface to the human approver / pause the conversation
        await escalate_to_human(request.conversation_id, exc)
    else:
        raise

Prevention

When it happens

Trigger: A run where each resume produces new tool-approval interrupts — e.g. a tool that keeps requesting approval, or resume payloads that fail to satisfy the interrupt — until the iteration cap is reached inside _invoke_until_text.

Common situations: Human-in-the-loop flows where an approver keeps rejecting and the agent keeps re-requesting; approval callbacks wired so the resumed Command does not actually resolve the interrupts; a looping agent policy that retries the same disallowed tool.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/6ebac61abdfad376. Report an issue: GitHub.