{"record":{"id":"f5b8d72c28499ef4","repo":"JuliusBrussee/caveman","slug":"use-asyncmiddlewareruntime-with-the-asynchronous-transport","errorCode":null,"errorMessage":"Use AsyncMiddlewareRuntime with the asynchronous transport","messagePattern":"Use AsyncMiddlewareRuntime with the asynchronous transport","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/middleware/python/caveman_middleware/google.py","lineNumber":464,"sourceCode":"                response.stream = _SyncStream(response.stream, attempt, \"text/event-stream\" in response.headers.get(\"content-type\", \"\"))\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 CavemanGoogleAsyncTransport(httpx.AsyncBaseTransport):\n    \"\"\"Async HTTPX transport with the runtime's bounded async execution path.\"\"\"\n    def __init__(self, *, runtime, scope, provider_base_url=\"https://generativelanguage.googleapis.com\", transport=None):\n        if isinstance(runtime, MiddlewareRuntime):\n            runtime = runtime.as_async()\n        if not isinstance(runtime, AsyncMiddlewareRuntime):\n            raise TypeError(\"Use AsyncMiddlewareRuntime with the asynchronous transport\")\n        self.runtime, self.scope, self.transport = runtime, scope, transport or httpx.AsyncHTTPTransport()\n        self.base = urlsplit(provider_base_url)\n\n    async def handle_async_request(self, request):\n        url = urlsplit(str(request.url))\n        if (url.scheme, url.netloc) != (self.base.scheme, self.base.netloc) or not url.path.startswith(self.base.path.rstrip(\"/\") + \"/\"):\n            return await self.transport.handle_async_request(request)\n        state = _prepare(request, self.runtime, self.scope)\n        if state is None:\n            return await self.transport.handle_async_request(request)\n        attempt, plan = state\n        outgoing = _apply(request, state, await self.runtime.optimize(**plan[2]) if plan else None)\n        attempt.observe(\"dispatch_intent\")\n        token = owner.set(attempt)\n        try:\n            response = await self.transport.handle_async_request(outgoing)\n            if response.status_code >= 400:\n                attempt.observe(\"failed\")","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/middleware/python/caveman_middleware/google.py#L446-L482","documentation":"CavemanGoogleAsyncTransport requires an AsyncMiddlewareRuntime; it transparently promotes a sync MiddlewareRuntime via runtime.as_async(), but any other type fails this TypeError. It guarantees the async HTTPX transport always runs through the async bounded execution path.","triggerScenarios":"Calling CavemanGoogleAsyncTransport(runtime=X, scope=...) where X is not MiddlewareRuntime and not AsyncMiddlewareRuntime — e.g. None, a string config value, or a custom runtime-like object.","commonSituations":"Async app wired with a sync runtime that was already discarded; passing the runtime factory/class instead of the instance; None because the runtime failed to initialize earlier and the error was swallowed.","solutions":["Pass a MiddlewareRuntime (auto-promoted via as_async()) or an AsyncMiddlewareRuntime as runtime=.","Ensure the runtime object is actually constructed and not None before building the transport.","For pure sync usage, switch to the synchronous CavemanGoogleTransport."],"exampleFix":"// before\ntransport = CavemanGoogleAsyncTransport(runtime=runtime_config, scope=scope)\n// after\ntransport = CavemanGoogleAsyncTransport(runtime=AsyncMiddlewareRuntime(...), scope=scope)","handlingStrategy":"type-guard","validationCode":"assert isinstance(runtime, (MiddlewareRuntime, AsyncMiddlewareRuntime)), 'runtime must be a Caveman runtime'\ntransport = CavemanGoogleAsyncTransport(runtime=runtime, scope=scope)","typeGuard":"def is_async_compatible(r): return isinstance(r, (MiddlewareRuntime, AsyncMiddlewareRuntime))","tryCatchPattern":"try:\n    transport = CavemanGoogleAsyncTransport(runtime=runtime, scope=scope)\nexcept TypeError:\n    transport = CavemanGoogleAsyncTransport(runtime=MiddlewareRuntime(...), scope=scope)","preventionTips":["Guard runtime is not None before building transports in async apps.","Rely on the adapter's auto-promotion: pass a sync MiddlewareRuntime rather than hand-rolled objects.","Centralize transport construction in one helper so the runtime type is checked once."],"tags":["type-mismatch","httpx","async","python","constructor"],"backgroundTag":"invalid-constructor-argument","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"}