langchain-ai/deepagents · error · RequestError
-32600
-32600
Error message
ACP limitation: this agent raised a free-form LangGraph interrupt(), which ACP cannot display. ACP only supports human-in-the-loop permission prompts with a fixed set of decisions (approve/reject/edit). Spec: https://agentclientprotocol.com/protocol/overview Fix: use LangChain HumanInTheLoopMiddleware-style interrupts (action_requests/review_configs). Docs: https://docs.langchain.com/oss/python/langchain/human-in-the-loop This is a protocol limitation, not a bug in the agent.
What it means
When the streamed agent emits a LangGraph `__interrupt__` whose value is not a dict, the ACP server cannot map it to ACP's fixed approve/reject/edit permission prompt and raises a JSON-RPC RequestError with code -32600. ACP only supports HumanInTheLoopMiddleware-style interrupts carrying `action_requests`/`review_configs`; free-form `interrupt()` payloads cannot be rendered by ACP clients. This is a protocol limitation, not a bug in your agent.
Source
Thrown at libs/acp/deepagents_acp/server.py:1034
_expected_len = 3 # (namespace, stream_mode, data)
if not isinstance(stream_chunk, tuple) or len(stream_chunk) != _expected_len:
continue
_namespace, stream_mode, data = stream_chunk
# Check for cancellation during streaming
if self._cancelled:
self._cancelled = False # Reset for next prompt
return PromptResponse(stop_reason="cancelled")
if stream_mode == "updates":
updates = data
if isinstance(updates, dict) and "__interrupt__" in updates:
interrupt_objs = updates.get("__interrupt__")
if interrupt_objs:
for interrupt_obj in interrupt_objs:
interrupt_value = interrupt_obj.value
if not isinstance(interrupt_value, dict):
raise RequestError(
-32600,
(
"ACP limitation: this agent raised a free-form "
"LangGraph interrupt(), which ACP cannot display.\n\n"
"ACP only supports human-in-the-loop permission "
"prompts with a fixed set of decisions "
"(approve/reject/edit).\n"
"Spec: https://agentclientprotocol.com/protocol/overview\n\n"
"Fix: use LangChain HumanInTheLoopMiddleware-style "
"interrupts (action_requests/review_configs).\n"
"Docs: https://docs.langchain.com/oss/python/langchain/"
"human-in-the-loop\n\n"
"This is a protocol limitation, not a bug in the agent."
),
{"interrupt_value": interrupt_value},
)
# The checkpoint backing this update may not be visible untilView on GitHub (pinned to a1af029e6e)
Solutions
- Replace the free-form `interrupt()` call with LangChain HumanInTheLoopMiddleware-style interrupts that emit dicts with `action_requests`/`review_configs`
- If you must keep the raw interrupt, wrap the payload as a dict matching ACP's expected permission-prompt schema
- Move the free-form HITL flow out of the ACP-served agent into a client-side or non-ACP pathway
- See the docs linked in the message: https://docs.langchain.com/oss/python/langchain/human-in-the-loop
Example fix
# before
reply = interrupt("Approve this write?")
# after
from langchain.agents.middleware import HumanInTheLoopMiddleware
# configure the middleware with action_requests/review_configs so the
# interrupt value is a dict ACP can render as approve/reject/edit Defensive patterns
Strategy: try-catch
Type guard
def is_acp_compatible_interrupt(value: object) -> bool:
return isinstance(value, dict) and "action_requests" in value Try / catch
try:
resp = await conn.prompt(blocks, session_id)
except RequestError as exc:
if exc.code == -32600 and "free-form" in str(exc):
# Agent used bare interrupt(); switch to HumanInTheLoopMiddleware
...
raise Prevention
- Use HumanInTheLoopMiddleware (action_requests/review_configs) for all HITL in ACP-served agents
- Audit agent code for bare `interrupt(...)` calls before exposing the agent via ACP
- Only emit dict-typed interrupt payloads matching ACP's permission-prompt schema
- Test the full prompt flow with an agent that triggers an interrupt before deploying
When it happens
Trigger: Calling `prompt()` against an agent that calls LangGraph's bare `interrupt(payload)` with a non-dict value (e.g. a string or dataclass), or a custom node interrupting with an unsupported payload shape, during `agent.astream(...)` in server.py:1031-1034.
Common situations: Porting an existing LangGraph agent to ACP without converting its raw `interrupt()` calls; hand-written HITL nodes using `interrupt('confirm?')`; library middleware or subgraphs that emit custom interrupt payloads the ACP bridge doesn't recognize.
Related errors
- Agent initialization failed
- Audio is not currently supported.
- Could not parse embedded resource block. Block expected eith
- 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/bf5ac97213f95fae.
Report an issue: GitHub.