Hmbown/CodeWhale · error · ValueError

ProviderKind::ALL uses unknown variants

Error message

ProviderKind::ALL uses unknown variants: {sorted(missing)}

What it means

After extracting the ProviderKind::ALL catalog, the script verifies every `Self::X` variant listed there has a mapping to a provider id (variant_to_id from the parse impl, plus the "Custom" -> "custom" meta-provider). Any variant in ALL without a mapping raises this ValueError. It is a consistency check that the enum's identity/parse impl covers every shipped variant.

Solutions

  1. Read the sorted variant names in the message; add a parse/alias arm for each in provider_kind.rs so variant_to_id includes them.
  2. If the variant should map to an existing id (alias), add it to the alias list for that id rather than a new id.
  3. If a variant was added to ALL by mistake, remove it from the ALL array.
  4. If the mapping scheme changed, update provider_kind_catalog_ids in scripts/check-provider-registry.py (e.g. the catalog_variant_to_id merge) accordingly.

Example fix

// before (provider_kind.rs parse)
"openai" => Ok(Self::OpenAI),
// after
"openai" => Ok(Self::OpenAI),
"newprovider" | "np" => Ok(Self::NewProvider),
Defensive patterns

Strategy: validation

Validate before calling

variants = set(re.findall(r"Self::(\w+)", all_block))
known = set(variant_to_id) | {"Custom"}
unknown = variants - known
assert not unknown, f"unmapped ProviderKind variants: {sorted(unknown)}"

Type guard

def all_variants_mapped(all_block: str, variant_to_id: dict) -> bool:
    variants = set(re.findall(r"Self::(\w+)", all_block))
    return variants <= (set(variant_to_id) | {"Custom"})

Try / catch

try:
    ids = provider_kind_catalog_ids(src)
except ValueError as e:
    print(e); sys.exit(1)  # message lists the offending variants

Prevention

When it happens

Trigger: Adding a new ProviderKind variant to the ALL array without also adding a parse/alias arm for it in provider_kind.rs, so `Self::NewKind` appears in ALL but not in variant_to_id built from the identity impl.

Common situations: A contributor adds a new provider enum variant and forgets to extend the parse match or alias table; a variant is intentionally added to ALL but meant to be unreachable, without registering its id.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/e07a299e70ac4040. Report an issue: GitHub.

Appendix: source

Thrown at scripts/check-provider-registry.py:221

        raise ValueError("provider!() invocations returned no providers")
    return ids


def provider_kind_catalog_ids(
    provider_kind_rs: str, variant_to_id: dict[str, str]
) -> set[str]:
    catalog = re.search(
        r"pub const ALL:\s*\[Self;\s*\d+\]\s*=\s*\[(.*?)\];",
        provider_kind_rs,
        flags=re.DOTALL,
    )
    if catalog is None:
        raise ValueError("crates/config/src/provider_kind.rs: missing ProviderKind::ALL")
    variants = set(re.findall(r"Self::(\w+)", catalog.group(1)))
    catalog_variant_to_id = {**variant_to_id, "Custom": "custom"}
    missing = variants - set(catalog_variant_to_id)
    if missing:
        raise ValueError(f"ProviderKind::ALL uses unknown variants: {sorted(missing)}")
    return {catalog_variant_to_id[variant] for variant in variants}


def api_provider_ids(tui_config_rs: str) -> dict[str, str]:
    # ApiProvider ids derive from ProviderKind ids (via delegation to .kind().as_str())
    # plus the legacy "deepseek-cn" variant that exists only in ApiProvider.
    variant_to_id = provider_kind_ids("")
    # ApiProvider::SiliconflowCn maps to ProviderKind::SiliconflowCN
    if "SiliconflowCN" in variant_to_id:
        variant_to_id["SiliconflowCn"] = variant_to_id["SiliconflowCN"]
    variant_to_id["DeepseekCN"] = "deepseek-cn"
    return variant_to_id


def provider_tables(config_rs: str) -> set[str]:
    struct_start = require_index(
        config_rs, "pub struct ProvidersToml", "crates/config/src/lib.rs"
    )

View on GitHub (pinned to 433685b202)