{"record":{"id":"28c5224c8c9013b4","repo":"Hmbown/CodeWhale","slug":"modelregistry-uses-unknown-provider-variants-sor","errorCode":null,"errorMessage":"ModelRegistry uses unknown provider variants: {sorted(missing)}","messagePattern":"ModelRegistry uses unknown provider variants: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scripts/check-provider-registry.py","lineNumber":219,"sourceCode":"    table = markdown_section(providers_md, \"## Shipped Providers\")\n    return set(re.findall(r\"^\\|\\s*`([^`]+)`\\s*\\|\", table, flags=re.MULTILINE))\n\n\ndef shipped_provider_tables(providers_md: str) -> set[str]:\n    table = markdown_section(providers_md, \"## Shipped Providers\")\n    return set(re.findall(r\"\\|\\s*`\\[providers\\.([a-z0-9_]+)\\]`\\s*\\|\", table))\n\n\ndef static_registry_provider_rows(providers_md: str) -> set[str]:\n    table = markdown_section(providers_md, \"## Static Model Registry\")\n    return set(re.findall(r\"^\\|\\s*`([^`]+)`\\s*\\|\", table, flags=re.MULTILINE))\n\n\ndef model_registry_providers(agent_rs: str, variant_to_id: dict[str, str]) -> set[str]:\n    variants = set(re.findall(r\"provider:\\s*ProviderKind::(\\w+)\", agent_rs))\n    missing = variants - set(variant_to_id)\n    if missing:\n        raise ValueError(f\"ModelRegistry uses unknown provider variants: {sorted(missing)}\")\n    return {variant_to_id[variant] for variant in variants}\n\n\ndef default_strings(tui_config_rs: str) -> set[str]:\n    # Model/base-URL constants now live in config/models.rs (#3311); scan it\n    # alongside config.rs so the check follows the leaf split.\n    sources = tui_config_rs + \"\\n\" + read(TUI_CONFIG_MODELS_RS)\n    defaults = set()\n    for name, value in re.findall(\n        r'const\\s+(DEFAULT_[A-Z0-9_]+(?:MODEL|BASE_URL)):\\s*&str\\s*=\\s*\"([^\"]+)\"',\n        sources,\n    ):\n        if name == \"DEFAULT_DEEPSEEKCN_BASE_URL\":\n            continue\n        defaults.add(value)\n    if not defaults:\n        raise ValueError(\"no default provider model/base URL constants found\")\n    return defaults","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-provider-registry.py#L201-L237","documentation":"model_registry_providers scans crates/agent/src/lib.rs for `provider: ProviderKind::<Variant>` entries and found variants absent from the variant-to-id map built from provider.rs (provider!() macros plus the manually listed impls). The static ModelRegistry may only reference providers that exist in the config crate with a known canonical id. The message lists the exact unknown variants.","triggerScenarios":"Adding a ModelRegistry entry for a provider before registering it in provider.rs; a typo in the variant name in agent.rs; renaming a ProviderKind variant in config without updating agent; implementing the provider in a way provider_kind_ids() does not recognize.","commonSituations":"Cross-crate provider onboarding done in the wrong order; rename refactors that miss crates/agent.","solutions":["For each listed variant, register the provider in crates/config/src/provider.rs via provider!() or a manual impl, extending the manual-impl list in provider_kind_ids() when the impl is hand-written","Fix typos or stale names in the `provider: ProviderKind::...` entries of crates/agent/src/lib.rs","Re-run the script; the docs table comparison only proceeds once variants resolve"],"exampleFix":"// before (crates/agent/src/lib.rs)\nprovider: ProviderKind::Newprovider,  // unknown to the checker's map\n// after (crates/config/src/provider.rs)\nprovider!(\n    Anthropic,\n    Newprovider,\n    \"newprovider\",\n    aliases: [],\n);","handlingStrategy":"validation","validationCode":"variants = set(re.findall(r'provider:\\s*ProviderKind::(\\w+)', agent_rs))\nunknown = variants - set(variant_to_id)\nassert not unknown, sorted(unknown)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register providers in the config crate before referencing them in ModelRegistry","Keep variant names in sync across crates during renames","Run the drift check after cross-crate provider edits"],"tags":["python","rust","provider-registry","static-analysis"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}