{"record":{"id":"8286185529bb0c6f","repo":"JuliusBrussee/caveman","slug":"unsupported-sync-router-strict","errorCode":"unsupported_sync_router_strict","errorMessage":"unsupported_sync_router_strict","messagePattern":"unsupported_sync_router_strict","errorType":"error_code","errorClass":"MiddlewareError","httpStatus":null,"severity":"error","filePath":"packages/middleware/python/caveman_middleware/litellm.py","lineNumber":308,"sourceCode":"            return function(**kwargs)\n        passive_reason = self._passive_reason(method, kwargs)\n        if passive_reason:\n            attempt = Attempt(self.runtime, None, str(uuid.uuid4()), str(uuid.uuid4()), passive=True,\n                              reason=passive_reason, adapter=\"litellm\")\n            attempt.observe(\"dispatch_intent\")\n            token = owner.set(attempt)\n            try:\n                return function(**kwargs)\n            finally:\n                owner.reset(token)\n        if not isinstance(self.runtime, MiddlewareRuntime):\n            raise TypeError(\"Synchronous LiteLLM calls require MiddlewareRuntime\")\n        router = isinstance(self.client, native.Router) and method == \"completion\"\n        if router and self.runtime.strict:\n            # Logging callbacks swallow their exceptions. Reject this capability\n            # before calling the Router so strict failure cannot dispatch a request.\n            self._report(\"unsupported_sync_router_strict\")\n            raise MiddlewareError(\"unsupported_sync_router_strict\")\n        if router and self._registrations == 0:\n            self._report(\"not_registered\")\n            raise RuntimeError(\"Use CavemanLiteLLM as a context manager while sync Router calls and streams are active\")\n        with self._activation(scope, kwargs, method) as (params, request):\n            if router:\n                token = _sync_router.set(self)\n                try:\n                    return function(**params)\n                finally:\n                    _sync_router.reset(token)\n            # Direct sync SDK calls already name the selected provider/model.\n            session = self._session(request, method, self.runtime) if self.client is native else None\n            token = owner.set(None)\n            try:\n                body, attempt = session.prepare(params) if session else (params, None)\n            finally:\n                owner.reset(token)\n            if attempt:","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/middleware/python/caveman_middleware/litellm.py#L290-L326","documentation":"Sync litellm.Router completion runs logging callbacks that swallow exceptions, so in strict mode a middleware failure could not abort the request — the strict guarantee would be silently broken. The adapter rejects this combination up front (before the Router dispatches) by reporting 'unsupported_sync_router_strict' and raising MiddlewareError with that code.","triggerScenarios":"Calling completion() while self.client is a litellm.Router, method is 'completion', and self.runtime.strict is True.","commonSituations":"Enabling strict mode in production config while still using the sync Router for load balancing/fallbacks; flipping runtime.strict on without migrating sync Router traffic to acompletion.","solutions":["Switch sync Router calls to await acompletion(...) (async path), keeping strict mode on","Disable strict mode on the MiddlewareRuntime if you must keep sync Router calls","Use a plain litellm client (non-Router) for sync completion calls","Gate strict mode per-environment so sync-Router deployments run non-strict"],"exampleFix":"// before\n# runtime = MiddlewareRuntime(strict=True); client = litellm.Router(...)\nadapter.completion(scope=scope, model=..., messages=...)  # MiddlewareError\n\n// after\nawait adapter.acompletion(scope=scope, model=..., messages=...)  # strict-safe","handlingStrategy":"try-catch","validationCode":"from litellm import Router\nif isinstance(adapter.client, Router) and getattr(adapter.runtime, \"strict\", False):\n    raise RuntimeError(\"sync Router completion is unsupported with strict=True; use acompletion or disable strict\")","typeGuard":"def sync_router_strict_supported(adapter) -> bool:\n    from litellm import Router\n    return not (isinstance(adapter.client, Router) and adapter.runtime.strict)","tryCatchPattern":"try:\n    return adapter.completion(scope=scope, **kwargs)\nexcept MiddlewareError as e:\n    if e.code == \"unsupported_sync_router_strict\":\n        return await adapter.acompletion(scope=scope, **kwargs)","preventionTips":["Use async Router calls (acompletion) whenever strict mode is enabled","Keep strict mode off for deployments pinned to sync Router traffic","Check the strict/Router combination in startup config validation","Read MiddlewareError.code to branch on specific capability rejections"],"tags":["python","middleware-error","strict-mode","sync-router","litellm"],"backgroundTag":"unsupported-operation","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"}