{"record":{"id":"c7d0b602db24638e","repo":"JuliusBrussee/caveman","slug":"expected-an-httpx2-asyncbasetransport","errorCode":null,"errorMessage":"Expected an HTTPX2 AsyncBaseTransport","messagePattern":"Expected an HTTPX2 AsyncBaseTransport","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/middleware/python/caveman_middleware/_httpx2.py","lineNumber":69,"sourceCode":"        try:\n            response = self.transport.handle_request(request)\n            observe_response(response, attempt)\n            return response\n        except BaseException:\n            attempt.observe(\"failed\")\n            raise\n        finally:\n            owner.reset(token)\n\n    def close(self):\n        self.transport.close()\n\n\nclass CavemanAsyncOpenAITransport(httpx2.AsyncBaseTransport):\n    \"\"\"Async counterpart of CavemanOpenAITransport, using the native pool.\"\"\"\n    def __init__(self, transport):\n        if not isinstance(transport, httpx2.AsyncBaseTransport):\n            raise TypeError(\"Expected an HTTPX2 AsyncBaseTransport\")\n        self.transport = transport\n\n    async def handle_async_request(self, request):\n        call = owner.get()\n        if not isinstance(call, OpenAICall) or call.transport is not self:\n            return await self.transport.handle_async_request(request)\n        attempt = call.next_attempt(request)\n        attempt.observe(\"dispatch_intent\")\n        token = owner.set(attempt)\n        try:\n            response = await self.transport.handle_async_request(request)\n            observe_response(response, attempt)\n            return response\n        except (asyncio.CancelledError, GeneratorExit):\n            attempt.observe(\"cancelled\")\n            raise\n        except BaseException:\n            attempt.observe(\"failed\")","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/middleware/python/caveman_middleware/_httpx2.py#L51-L87","documentation":"CavemanAsyncOpenAITransport is the async counterpart of the OpenAI interception transport and delegates handle_async_request to the supplied transport. It requires an httpx2.AsyncBaseTransport so delegation is guaranteed to support async handling.","triggerScenarios":"Constructing CavemanAsyncOpenAITransport with a sync httpx2.BaseTransport (like HTTPTransport), an httpx (v1) async transport, None, or any non-async transport object.","commonSituations":"Reusing the sync wrapper's transport in the async wrapper after copy-pasting setup code; mixing httpx/httpx2 after migration; passing httpx2.HTTPTransport where AsyncHTTPTransport is required.","solutions":["Pass an httpx2.AsyncBaseTransport, e.g. httpx2.AsyncHTTPTransport()","Swap the sync CavemanOpenAITransport usage for the async class only with async transports","Verify imports point at httpx2, not httpx","isinstance(transport, httpx2.AsyncBaseTransport) check before construction"],"exampleFix":"# before\ntransport = CavemanAsyncOpenAITransport(httpx2.HTTPTransport())  # TypeError: sync transport\n# after\ntransport = CavemanAsyncOpenAITransport(httpx2.AsyncHTTPTransport())","handlingStrategy":"type-guard","validationCode":"def ensure_async_transport(transport):\n    if not isinstance(transport, httpx2.AsyncBaseTransport):\n        raise TypeError(\"transport must be an httpx2.AsyncBaseTransport\")\n    return transport","typeGuard":"def is_async_transport(transport) -> bool:\n    return isinstance(transport, httpx2.AsyncBaseTransport)","tryCatchPattern":"try:\n    transport = CavemanAsyncOpenAITransport(candidate)\nexcept TypeError as e:\n    if \"AsyncBaseTransport\" in str(e):\n        candidate = httpx2.AsyncHTTPTransport()\n        transport = CavemanAsyncOpenAITransport(candidate)","preventionTips":["Never share a sync transport between sync and async clients","Keep a single factory per client kind that constructs the right transport type","Pin httpx2 versions in lockfiles to avoid attribute drift","Type-annotate transport params as httpx2.AsyncBaseTransport"],"tags":["python","httpx2","async","transport"],"backgroundTag":"type-mismatch","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}