{"record":{"id":"2ac741b87969e386","repo":"crewAIInc/crewAI","slug":"failed-to-communicate-with-agent-handler-api-e-s","errorCode":null,"errorMessage":"Failed to communicate with Agent Handler API: {e!s}","messagePattern":"Failed to communicate with Agent Handler API: (.+?)","errorType":"exception","errorClass":"MergeAgentHandlerToolError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/merge_agent_handler_tool/merge_agent_handler_tool.py","lineNumber":113,"sourceCode":"\n        try:\n            response = requests.post(url, json=payload, headers=headers, timeout=60)\n            response.raise_for_status()\n            result = response.json()\n\n            if \"error\" in result:\n                error_msg = result[\"error\"].get(\"message\", \"Unknown error\")\n                error_code = result[\"error\"].get(\"code\", -1)\n                logger.error(\n                    f\"Agent Handler API error (code {error_code}): {error_msg}\"\n                )\n                raise MergeAgentHandlerToolError(f\"API Error: {error_msg}\")\n\n            return cast(dict[str, Any], result)\n\n        except requests.exceptions.RequestException as e:\n            logger.error(f\"Failed to call Agent Handler API: {e!s}\")\n            raise MergeAgentHandlerToolError(\n                f\"Failed to communicate with Agent Handler API: {e!s}\"\n            ) from e\n\n    def _run(self, **kwargs: Any) -> Any:\n        \"\"\"Execute the Agent Handler tool with the given arguments.\"\"\"\n        try:\n            logger.info(f\"Executing {self.tool_name} with arguments: {kwargs}\")\n\n            result = self._make_mcp_request(\n                method=\"tools/call\",\n                params={\"name\": self.tool_name, \"arguments\": kwargs},\n            )\n\n            if \"result\" in result and \"content\" in result[\"result\"]:\n                content = result[\"result\"][\"content\"]\n                if content and len(content) > 0:\n                    text_content = content[0].get(\"text\", \"\")\n                    try:","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/merge_agent_handler_tool/merge_agent_handler_tool.py#L95-L131","documentation":"Wraps any requests.exceptions.RequestException (connection error, DNS failure, timeout after 60s, TLS error, 4xx/5xx from raise_for_status) encountered while POSTing the JSON-RPC payload to the Agent Handler API. The original exception is chained, so the network-level cause is preserved in __cause__.","triggerScenarios":"Base URL unreachable (custom base_url wrong, DNS failure); corporate proxy/firewall blocking https://ah-api.merge.dev; the 60-second timeout exceeded by a slow tool pack call; server-side 5xx causing raise_for_status() to raise HTTPError.","commonSituations":"Ephemeral network blips in long-running agent jobs; air-gapped or proxied environments; typos in a custom base_url; transient Merge API incidents.","solutions":["Retry the call — transient network/5xx failures are the most common cause (wrap in retry with backoff)","Verify connectivity: curl -v https://ah-api.merge.dev from the same host/proxy settings","If a custom base_url is set, check it for typos and that it speaks the same /api/v1/... contract","For slow tools, reduce payload or accept that calls over 60s will always time out and need a different approach"],"exampleFix":"# before\nresult = tool._run(**kwargs)  # MergeAgentHandlerToolError on blip\n\n# after\nimport time\nfrom crewai_tools.tools.merge_agent_handler_tool.merge_agent_handler_tool import MergeAgentHandlerToolError\n\nfor attempt in range(3):\n    try:\n        result = tool._run(**kwargs)\n        break\n    except MergeAgentHandlerToolError as e:\n        if \"Failed to communicate\" not in str(e) or attempt == 2:\n            raise\n        time.sleep(2 ** attempt)","handlingStrategy":"retry","validationCode":"import socket, requests\n\ndef endpoint_reachable(base_url: str = \"https://ah-api.merge.dev\", timeout: float = 5.0) -> bool:\n    try:\n        requests.get(base_url, timeout=timeout)\n        return True\n    except requests.exceptions.RequestException:\n        return False","typeGuard":null,"tryCatchPattern":"import time\nfrom crewai_tools.tools.merge_agent_handler_tool.merge_agent_handler_tool import MergeAgentHandlerToolError\n\nlast = None\nfor attempt in range(3):\n    try:\n        result = tool._run(**kwargs)\n        break\n    except MergeAgentHandlerToolError as e:\n        if \"Failed to communicate\" not in str(e):\n            raise\n        last = e\n        time.sleep(2 ** attempt)\nelse:\n    raise last","preventionTips":["Wrap Agent Handler calls in bounded exponential-backoff retry","Add a pre-flight connectivity check to base_url in deployment healthchecks","Keep calls under the 60s client timeout or split large workloads"],"tags":["network","timeout","retry","merge","crewai-tools"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}