{"record":{"id":"a709b91b83902bbe","repo":"langchain-ai/deepagents","slug":"offload-server-returned-an-invalid-operation-respo","errorCode":null,"errorMessage":"Offload server returned an invalid operation response.","messagePattern":"Offload server returned an invalid operation response\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/client/remote_client.py","lineNumber":439,"sourceCode":"                # older than this operation, never registers the dcode HTTP app,\n                # and the SDK's bare \"404 Not Found\" names neither the cause nor\n                # a fix.\n                msg = (\n                    \"This server does not provide dcode's /offload operation. \"\n                    \"Use the built-in dcode server, or upgrade the server to a \"\n                    \"version that registers it.\"\n                )\n                raise RuntimeError(msg) from exc\n            if not isinstance(response, dict):\n                msg = \"Offload server returned a non-object response.\"\n                raise TypeError(msg)\n            status = response.get(\"status\")\n            if status == \"complete\":\n                return _validated_offload_result(response.get(\"result\"))\n            request = response.get(\"request\")\n            if status != \"interrupt\" or not is_hook_interrupt_payload(request):\n                msg = \"Offload server returned an invalid operation response.\"\n                raise RuntimeError(msg)\n            invocation = request.get(\"request\")\n            invocation_id = (\n                invocation.get(\"invocation_id\")\n                if isinstance(invocation, dict)\n                else None\n            )\n            if not isinstance(invocation_id, str) or not invocation_id:\n                msg = \"Offload hook request has no invocation id.\"\n                raise RuntimeError(msg)\n            logger.debug(\n                \"Offload round %d fulfilling hook invocation %s\",\n                round_index,\n                invocation_id,\n            )\n            if round_index == _OFFLOAD_MAX_RESUME_ROUNDS:\n                # The extra iteration exists to POST the last fulfillment and\n                # read the result, not to answer one more hook. Without this the\n                # loop fulfills 33 hooks and then reports \"after 32 rounds\".","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/remote_client.py#L421-L457","documentation":"When the offload response's `status` is not `\"complete\"`, the client requires it to be `\"interrupt\"` with a request payload that satisfies `is_hook_interrupt_payload` (a valid Hooks v2 hook-interrupt). Any other status, a missing `request`, or a malformed interrupt payload triggers this RuntimeError — the server spoke an offload protocol the client cannot drive.","triggerScenarios":"Server returns `status` values other than `complete`/`interrupt` (e.g. `\"error\"`, `\"pending\"`, null), or `status == \"interrupt\"` but `request` is missing or fails `is_hook_interrupt_payload` (wrong keys/shapes in the hook interrupt).","commonSituations":"A server version drift where the interrupt payload schema changed; a custom/in-house offload route emitting its own status names; a hook executor version mismatch causing payload keys to be renamed server-side.","solutions":["Align server and client versions — the hook-interrupt payload schema must match `is_hook_interrupt_payload` in `deepagents_code.hooks.interrupt`.","Log the raw offload response to see the actual `status`/`request` and compare against the expected schema.","If you run a custom server, make it return only `status: \"complete\"` or `status: \"interrupt\"` with a spec-conformant hook-interrupt request.","Check for middleware or serialization layers on the server that strip or rename payload fields."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"from deepagents_code.hooks.interrupt import is_hook_interrupt_payload\n\ndef is_valid_offload_interrupt(response: object) -> bool:\n    return (\n        isinstance(response, dict)\n        and response.get(\"status\") == \"interrupt\"\n        and is_hook_interrupt_payload(response.get(\"request\"))\n    )","tryCatchPattern":"try:\n    result = await agent.aoffload(config=config, context=ctx, fulfill_hook=hook)\nexcept RuntimeError as exc:\n    if \"invalid operation response\" in str(exc):\n        logging.error(\"Offload status/payload not understood; check server-client schema match\")\n    else:\n        raise","preventionTips":["Match the hook-interrupt schema against `is_hook_interrupt_payload` whenever either side changes.","Upgrade server and client in lockstep.","Test offload round-trips against the real server, not just mocks, when touching hook payloads."],"tags":["protocol","schema","offload","hooks"],"backgroundTag":"invalid-server-response-shape","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}