{"record":{"id":"a9de7d511107eb12","repo":"BerriAI/litellm","slug":"no-models-configured-for-tier-tier-key","errorCode":null,"errorMessage":"No models configured for tier {tier_key}","messagePattern":"No models configured for tier (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/router_strategy/complexity_router/complexity_router.py","lineNumber":1200,"sourceCode":"        self,\n        tier: ComplexityTier,\n        raw_messages: list[dict[str, Any]] | None,\n        resolved_messages: list[dict[str, Any]] | None,\n        request_kwargs: dict,\n    ) -> str:\n        if not self.config.plugins:\n            return self.get_model_for_tier(tier)\n\n        from litellm.types.router import RoutingContext\n\n        tier_key: Final = tier.value\n        metadata_key: Final = \"litellm_metadata\" if \"litellm_metadata\" in request_kwargs else \"metadata\"\n        pool: Final = tuple(self._tier_pools().get(tier_key, ()))\n        if not pool:\n            # Nothing for the plugins to filter. Falling through would raise the\n            # plugin-filtering error below and send the operator hunting for a policy\n            # plugin that never ran, so name the real problem: the tier has no models.\n            raise ValueError(f\"No models configured for tier {tier_key}\")\n        context = RoutingContext(\n            raw_messages=raw_messages or [],\n            structured_messages=resolved_messages or [],\n            candidate_models=list(pool),\n            metadata=request_kwargs.get(metadata_key) or {},\n        )\n        for plugin in self.config.plugins:\n            context = await plugin.run(context)\n\n        if not context.candidate_models:\n            # A plugin narrowing a tier to zero candidates is a policy decision (e.g. no\n            # model this tenant's budget allows) -- falling back to default_model here\n            # (which was never checked against the plugins) would let that policy be\n            # silently bypassed. Raise instead, matching the Router-level plugin\n            # pipeline's own fail-closed behavior for the same situation.\n            raise ValueError(f\"No candidate models left for tier {tier_key} after routing-plugin filtering\")\n        return self._pick_from_tier_value(context.candidate_models, tier_key)\n","sourceCodeStart":1182,"sourceCodeEnd":1218,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/router_strategy/complexity_router/complexity_router.py#L1182-L1218","documentation":"Routing guard in the complexity router: the tier has no entry in config.tiers at all (and no default_model fallback applied), so the router cannot map this complexity tier to any model.","triggerScenarios":"Thrown at litellm/router_strategy/complexity_router/complexity_router.py:1200 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Configure models for the tier in the complexity router config."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}