Hmbown/CodeWhale · error · ValueError

expected a hand-written `impl Provider for

Error message

expected a hand-written `impl Provider for {variant_name}` with id {id_literal!r}; the guard's floor is stale

What it means

provider_kind_ids() pairs each provider!() invocation's variant with the id from the hand-written `impl Provider for <Variant>` (its fn id). This error means the regex found no such impl returning the expected id literal for a variant, so the guard's floor list is out of date with the actual Rust code. The message explicitly says the guard's floor is stale.

Solutions

  1. Update the guard's expected id literal list to match the current `fn id` return values in the Rust source
  2. Restore the hand-written `impl Provider for <Variant>` with the expected id if it was accidentally removed or macro-generated
  3. Sync the provider!() invocations and impls after any provider rename so both sides agree

Example fix

// before: guard expects id "huggingface" but impl returns "hf"
// after:  update guard floor to ("Huggingface", "hf") or change fn id to "huggingface" in the impl
Defensive patterns

Strategy: validation

Validate before calling

for variant, expected_id in floor:
    if not re.search(rf'impl\s+Provider\s+for\s+{variant}.*?fn\s+id.*?"{expected_id}"', provider_rs, re.DOTALL):
        print(f"stale floor: {variant}")

Try / catch

try:
    ids = provider_kind_ids(provider_rs)
except ValueError as e:
    print(f"registry guard out of date: {e}", file=sys.stderr)
    sys.exit(1)

Prevention

When it happens

Trigger: Called from api_provider_ids or main when a variant listed in provider!() invocations has no `impl Provider for <Variant>` containing `fn id` returning the expected id literal — e.g. the id string changed, the impl is now generated by macro, or the variant's impl was removed.

Common situations: Renaming a provider id string in Rust without updating the guard; switching from hand-written impls to macro-generated ids; deleting a provider while the guard still expects it; a repo state from before/after the config module split.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

        ("Openmodel", "openmodel"),
        ("MinimaxAnthropic", "minimax-anthropic"),
        ("OpencodeZen", "opencode-zen"),
        # Alibaba Model Studio ships four plan/dialect identities, each with a
        # hand-written impl Provider for the same reason as the rows above:
        # the wire policy is not fixed, so provider!() cannot express them.
        ("ModelstudioTokenPlan", "modelstudio-token-plan"),
        ("ModelstudioTokenPlanAnthropic", "modelstudio-token-plan-anthropic"),
        ("ModelstudioCodingPlan", "modelstudio-coding-plan"),
        ("ModelstudioCodingPlanAnthropic", "modelstudio-coding-plan-anthropic"),
    ]:
        match = re.search(
            rf'impl\s+Provider\s+for\s+{variant_name}.*?fn\s+id.*?\"({id_literal})\"',
            provider_rs, re.DOTALL,
        )
        if match:
            ids[variant_name] = match.group(1)
        elif variant_name not in ids:
            raise ValueError(
                f"expected a hand-written `impl Provider for {variant_name}` "
                f"with id {id_literal!r}; the guard's floor is stale"
            )
    if not ids:
        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")

View on GitHub (pinned to 433685b202)