{"record":{"id":"81f2665b88275cc1","repo":"affaan-m/ECC","slug":"unknown-provider-type-provider-type-valid-type","errorCode":null,"errorMessage":"Unknown provider type: {provider_type}. Valid types: {[p.value for p in ProviderType]}","messagePattern":"Unknown provider type: (.+?)\\. Valid types: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/llm/providers/resolver.py","lineNumber":69,"sourceCode":"    if provider_type is not None:\n        return provider_type\n\n    env_provider = os.environ.get(\"LLM_PROVIDER\")\n    if env_provider:\n        return _strip_env_value(env_provider).lower()\n\n    saved_config = _read_saved_llm_config()\n    return saved_config.get(\"LLM_PROVIDER\", \"claude\").lower()\n\n\ndef get_provider(provider_type: ProviderType | str | None = None, **kwargs: str) -> LLMProvider:\n    provider_type = _resolve_provider_type(provider_type)\n\n    if isinstance(provider_type, str):\n        try:\n            provider_type = ProviderType(provider_type)\n        except ValueError:\n            raise ValueError(f\"Unknown provider type: {provider_type}. Valid types: {[p.value for p in ProviderType]}\")\n\n    provider_cls = _PROVIDER_MAP.get(provider_type)\n    if not provider_cls:\n        raise ValueError(f\"No provider registered for type: {provider_type}\")\n\n    return provider_cls(**kwargs)\n\n\ndef register_provider(provider_type: ProviderType, provider_cls: type[LLMProvider]) -> None:\n    _PROVIDER_MAP[provider_type] = provider_cls\n","sourceCodeStart":51,"sourceCodeEnd":80,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/src/llm/providers/resolver.py#L51-L80","documentation":"resolver.get_provider() first normalizes the provider_type argument; if it is still a string, it attempts ProviderType(value). On failure it raises ValueError 'Unknown provider type: ...' listing valid enum values. This guards against typo'd or unsupported provider names.","triggerScenarios":"Calling get_provider(\"claud\") or get_provider(\"gpt4\") — any string not matching a ProviderType member's value.","commonSituations":"Reading provider name from config/env with typos; passing display names ('ChatGPT', 'Anthropic') instead of enum values ('openai', 'claude'); config written for an older version whose enum values changed.","solutions":["Use a valid ProviderType value string (e.g. 'claude', 'openai', 'ollama') or pass the ProviderType enum directly","Compare against [p.value for p in ProviderType] to see accepted values","Validate the config value at load time against the enum","Fix typos in .env/config files that supply the provider name"],"exampleFix":"// before\nprovider = get_provider(config[\"llm\"])  # \"Claude\"\n// after\nprovider = get_provider(config[\"llm\"].lower())  # \"claude\"","handlingStrategy":"validation","validationCode":"VALID = {p.value for p in ProviderType}\nassert provider_name in VALID, f\"{provider_name!r} not in {sorted(VALID)}\"\nprovider = get_provider(provider_name)","typeGuard":"def is_provider_type(v: str) -> bool:\n    try:\n        ProviderType(v)\n        return True\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    provider = get_provider(provider_type)\nexcept ValueError as e:\n    logger.error(\"Bad provider config: %s\", e)\n    provider = get_provider(ProviderType.OPENAI)  # safe default","preventionTips":["Validate provider names from config/env at load time against ProviderType","Normalize casing/lowercase of config values","Add a schema validation (pydantic Literal) for provider fields","Keep config docs listing valid provider values"],"tags":["validation","enum","resolver"],"backgroundTag":"invalid-enum-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}