{"record":{"id":"e2553ed98652efc7","repo":"headroomlabs-ai/headroom","slug":"no-optimizer-registered-for-key-available-a","errorCode":null,"errorMessage":"No optimizer registered for '{key}'. Available: {available}","messagePattern":"No optimizer registered for '(.+?)'\\. Available: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"headroom/cache/registry.py","lineNumber":109,"sourceCode":"\n        Returns:\n            Cache optimizer instance\n\n        Raises:\n            KeyError: If no optimizer registered for provider/tier\n        \"\"\"\n        # Build the lookup key\n        if tier != \"oss\":\n            key = f\"{provider}-{tier}\"\n            # Fall back to OSS if enterprise not available\n            if key not in cls._optimizers:\n                key = provider\n        else:\n            key = provider\n\n        if key not in cls._optimizers:\n            available = list(cls._optimizers.keys())\n            raise KeyError(f\"No optimizer registered for '{key}'. Available: {available}\")\n\n        # Return cached instance if requested\n        cache_key = f\"{key}:{id(config)}\" if config else key\n        if cached and cache_key in cls._instances:\n            return cls._instances[cache_key]\n\n        # Create new instance\n        optimizer_class = cls._optimizers[key]\n        instance = optimizer_class(config)\n\n        if cached:\n            cls._instances[cache_key] = instance\n\n        return instance\n\n    @classmethod\n    def list_providers(cls) -> list[str]:\n        \"\"\"List all registered provider names (excluding tier suffixes).\"\"\"","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/cache/registry.py#L91-L127","documentation":"The optimizer registry (headroom/cache/registry.py) maps provider or provider-tier keys to optimizer classes. get_optimizer builds a key f\"{provider}-{tier}\" for non-oss tiers and falls back to the bare provider name if that enterprise key is absent; if neither is registered it raises KeyError listing the available keys. The error therefore means neither the tier-specific nor the base provider optimizer was registered — typically because the provider module that registers it was never imported.","triggerScenarios":"Calling OptimizerRegistry.get(...) (or the cache API that delegates to it) with provider='anthropic', tier='enterprise' when only 'anthropic' or only OSS optimizers are registered; or any provider whose registering module (e.g. the anthropic/openai optimizer module) has not been imported yet, since registration happens at import time.","commonSituations":"Passing an enterprise tier without the enterprise extra installed; refactors that removed an import side effect; typo'd provider names ('Anthropic' vs 'anthropic'); running a minimal install where only some provider optimizers are available.","solutions":["Import the module that registers the optimizer before calling get (e.g. from headroom.cache import anthropic_optimizer) so its @OptimizerRegistry.register decorator runs","Use a key from the 'Available: [...]' list in the message — match provider name and drop to tier='oss' if the enterprise variant isn't registered","Verify spelling and case of provider ('anthropic', 'openai', 'google') against the registered keys","If you implemented a custom optimizer, register it explicitly with OptimizerRegistry.register(key, cls)"],"exampleFix":"# before\nopt = OptimizerRegistry.get(provider=\"anthropic\", tier=\"enterprise\")  # KeyError\n\n# after\nfrom headroom.cache.anthropic_optimizer import register as _reg  # side-effect registers key\n_reg()\nopt = OptimizerRegistry.get(provider=\"anthropic\", tier=\"oss\")","handlingStrategy":"validation","validationCode":"from headroom.cache.registry import OptimizerRegistry\nkey = f\"{provider}-{tier}\" if tier != \"oss\" else provider\nif key not in OptimizerRegistry._optimizers and provider not in OptimizerRegistry._optimizers:\n    raise SystemExit(f\"optimizer {key!r} not registered; import its module first\")","typeGuard":"def optimizer_available(provider: str, tier: str = \"oss\") -> bool:\n    from headroom.cache.registry import OptimizerRegistry\n    opts = OptimizerRegistry._optimizers\n    return (f\"{provider}-{tier}\" if tier != \"oss\" else provider) in opts or provider in opts","tryCatchPattern":"try:\n    opt = OptimizerRegistry.get(provider=provider, tier=tier, config=cfg)\nexcept KeyError as e:\n    opt = OptimizerRegistry.get(provider=provider, tier=\"oss\", config=cfg)  # downgrade tier","preventionTips":["Import all provider optimizer modules once at app startup so registrations are side-effected","Normalize provider strings to lowercase at config load time","Unit-test that every provider you configure resolves before deploying"],"tags":["cache","registry","provider","keyerror","lazy-import"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}