{"record":{"id":"bf5ac97213f95fae","repo":"langchain-ai/deepagents","slug":"32600","errorCode":"-32600","errorMessage":"ACP limitation: this agent raised a free-form LangGraph interrupt(), which ACP cannot display.\n\nACP only supports human-in-the-loop permission prompts with a fixed set of decisions (approve/reject/edit).\nSpec: https://agentclientprotocol.com/protocol/overview\n\nFix: use LangChain HumanInTheLoopMiddleware-style interrupts (action_requests/review_configs).\nDocs: https://docs.langchain.com/oss/python/langchain/human-in-the-loop\n\nThis is a protocol limitation, not a bug in the agent.","messagePattern":"ACP limitation: this agent raised a free-form LangGraph interrupt\\(\\), which ACP cannot display\\.\n\nACP only supports human-in-the-loop permission prompts with a fixed set of decisions \\(approve/reject/edit\\)\\.\nSpec: https://agentclientprotocol\\.com/protocol/overview\n\nFix: use LangChain HumanInTheLoopMiddleware-style interrupts \\(action_requests/review_configs\\)\\.\nDocs: https://docs\\.langchain\\.com/oss/python/langchain/human-in-the-loop\n\nThis is a protocol limitation, not a bug in the agent\\.","errorType":"error_code","errorClass":"RequestError","httpStatus":null,"severity":"error","filePath":"libs/acp/deepagents_acp/server.py","lineNumber":1034,"sourceCode":"                _expected_len = 3  # (namespace, stream_mode, data)\n                if not isinstance(stream_chunk, tuple) or len(stream_chunk) != _expected_len:\n                    continue\n\n                _namespace, stream_mode, data = stream_chunk\n                # Check for cancellation during streaming\n                if self._cancelled:\n                    self._cancelled = False  # Reset for next prompt\n                    return PromptResponse(stop_reason=\"cancelled\")\n\n                if stream_mode == \"updates\":\n                    updates = data\n                    if isinstance(updates, dict) and \"__interrupt__\" in updates:\n                        interrupt_objs = updates.get(\"__interrupt__\")\n                        if interrupt_objs:\n                            for interrupt_obj in interrupt_objs:\n                                interrupt_value = interrupt_obj.value\n                                if not isinstance(interrupt_value, dict):\n                                    raise RequestError(\n                                        -32600,\n                                        (\n                                            \"ACP limitation: this agent raised a free-form \"\n                                            \"LangGraph interrupt(), which ACP cannot display.\\n\\n\"\n                                            \"ACP only supports human-in-the-loop permission \"\n                                            \"prompts with a fixed set of decisions \"\n                                            \"(approve/reject/edit).\\n\"\n                                            \"Spec: https://agentclientprotocol.com/protocol/overview\\n\\n\"\n                                            \"Fix: use LangChain HumanInTheLoopMiddleware-style \"\n                                            \"interrupts (action_requests/review_configs).\\n\"\n                                            \"Docs: https://docs.langchain.com/oss/python/langchain/\"\n                                            \"human-in-the-loop\\n\\n\"\n                                            \"This is a protocol limitation, not a bug in the agent.\"\n                                        ),\n                                        {\"interrupt_value\": interrupt_value},\n                                    )\n\n                            # The checkpoint backing this update may not be visible until","sourceCodeStart":1016,"sourceCodeEnd":1052,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/acp/deepagents_acp/server.py#L1016-L1052","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nreply = interrupt(\"Approve this write?\")\n# after\nfrom langchain.agents.middleware import HumanInTheLoopMiddleware\n# configure the middleware with action_requests/review_configs so the\n# interrupt value is a dict ACP can render as approve/reject/edit","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_acp_compatible_interrupt(value: object) -> bool:\n    return isinstance(value, dict) and \"action_requests\" in value","tryCatchPattern":"try:\n    resp = await conn.prompt(blocks, session_id)\nexcept RequestError as exc:\n    if exc.code == -32600 and \"free-form\" in str(exc):\n        # Agent used bare interrupt(); switch to HumanInTheLoopMiddleware\n        ...\n    raise","preventionTips":["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"],"tags":["acp","interrupt","human-in-the-loop","protocol-limitation","json-rpc"],"backgroundTag":"unsupported-interrupt-payload","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}