BerriAI/litellm · error · ValueError

plugins and adaptive=True cannot both be set: adaptive's ban

Error message

plugins and adaptive=True cannot both be set: adaptive's bandit selection doesn't yet consume plugin-narrowed candidate pools. Disable adaptive or remove plugins.

What it means

Config validator on ComplexityRouterConfig: both routing plugins and adaptive=True are set, but the adaptive bandit does not yet consume plugin-narrowed candidate pools, so the combination is unsupported — disable one.

Source

Thrown at litellm/router_strategy/complexity_router/config.py:694

                f"and the classifier rubric ambiguous: {', '.join(shadowed)}"
            )
        labeled: Final = self.labeled_tiers()
        folded_labels: Final = tuple(label.casefold() for _, label in labeled)
        duplicated: Final = tuple(
            " and ".join(tier.value for tier, label in labeled if label.casefold() == folded)
            for position, folded in enumerate(folded_labels)
            if folded_labels.count(folded) > 1 and folded_labels.index(folded) == position
        )
        if duplicated:
            raise ValueError(
                f"tier_labels values must be unique across tiers; shared labels for: {'; '.join(duplicated)}"
            )
        return self

    @model_validator(mode="after")
    def _validate_plugins_adaptive_combo(self) -> "ComplexityRouterConfig":
        if self.plugins and self.adaptive:
            raise ValueError(
                "plugins and adaptive=True cannot both be set: adaptive's bandit selection doesn't yet "
                "consume plugin-narrowed candidate pools. Disable adaptive or remove plugins."
            )
        return self

    def tier_label(self, tier: ComplexityTier) -> str:
        """Operator-facing display name for a tier, falling back to its canonical name."""
        return self.tier_labels.get(tier, "").strip() or tier.value

    def labeled_tiers(self) -> tuple[tuple[ComplexityTier, str], ...]:
        """Every tier paired with its display name, in ascending severity order."""
        return tuple((tier, self.tier_label(tier)) for tier in TIER_SEVERITY_ORDER)

    def tier_for_label(self, label: str) -> ComplexityTier | None:
        """Resolve a display name back to its tier, case-insensitively, then canonical names."""
        folded: Final = label.strip().casefold()
        labeled: Final = self.labeled_tiers()
        return next(

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Disable adaptive or remove plugins; both cannot be set together.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at litellm/router_strategy/complexity_router/config.py:694 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/9d1c2b96063f5529. Report an issue: GitHub.