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
- Increase the runtime's approval-interrupt limit if long approval chains are legitimate
- Fix the approval handler/_build_approval_resume wiring so a resume actually satisfies the pending interrupts
- 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
- Ensure approval handlers actually resolve interrupts on resume (accept or reject) rather than no-op
- Add agent prompt constraints against re-requesting rejected tools
- Size the approval-interrupt limit to your real human-in-the-loop flow
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
- agent returned approval interrupts without resumable ids
- -32600
- Human decision count does not match Manual pending calls
- Human decision count does not match pending approval calls
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/6ebac61abdfad376.
Report an issue: GitHub.