Panniantong/Agent-Reach · error · TranscribeError

unknown provider: {provider} (use groq|openai|auto)

Error message

unknown provider: {provider} (use groq|openai|auto)

What it means

Raised by _provider_order (transcribe.py:397-402), reached from transcribe() when the provider argument is neither 'auto' nor a key of PROVIDERS. Unlike transcribe_chunk's error, 'auto' IS valid here; anything outside {auto, groq, openai} is rejected before any key check or download work.

Source

Thrown at agent_reach/transcribe.py:402

                headers={"Authorization": f"Bearer {key}"},
                files={"file": (chunk.name, fh, "audio/m4a")},
                data={"model": info["model"], "response_format": "text"},
                timeout=timeout,
            )
        except requests.RequestException as e:
            raise TranscribeError(f"{provider}: network error: {e}") from e

    if not resp.ok:
        raise TranscribeError(f"{provider}: HTTP {resp.status_code}: {resp.text[:300]}")
    return resp.text


def _provider_order(provider: str) -> List[str]:
    if provider == "auto":
        return ["groq", "openai"]
    if provider in PROVIDERS:
        return [provider]
    raise TranscribeError(f"unknown provider: {provider} (use groq|openai|auto)")


def transcribe(
    source: str,
    *,
    provider: str = "auto",
    out_dir: Optional[Path] = None,
    config: Optional[Config] = None,
    allow_provider_fallback: bool = False,
) -> str:
    """Transcribe a URL or local file path. Returns the joined transcript text.

    `provider` is one of `auto`, `groq`, or `openai`. Auto mode selects the
    first configured provider (Groq, then OpenAI). In auto mode only, set
    `allow_provider_fallback=True` to permit sending failed chunks to the next
    configured provider; using the flag with an explicit provider is rejected.
    `out_dir` defaults to a fresh temp directory; intermediate files stay there.
    """

View on GitHub (pinned to 93ae1d18c3)

Solutions

  1. Use one of 'auto', 'groq', 'openai' exactly (lowercase)
  2. Normalize input before the call: provider = provider.strip().lower() and validate against agent_reach.transcribe.PROVIDERS | {'auto'}
  3. Prefer provider='auto' when the caller has no strong preference — it picks the first configured provider

Example fix

# before
text = transcribe(url, provider="Groq")  # unknown provider: Groq (use groq|openai|auto)

# after
from agent_reach.transcribe import PROVIDERS
provider = provider.strip().lower()
if provider != "auto" and provider not in PROVIDERS:
    raise ValueError(f"provider must be auto or one of {sorted(PROVIDERS)}")
text = transcribe(url, provider=provider)
Defensive patterns

Strategy: type-guard

Validate before calling

from agent_reach.transcribe import PROVIDERS

def valid_transcribe_provider(name: str) -> bool:
    return name == "auto" or name in PROVIDERS

Type guard

from typing import Literal
from agent_reach.transcribe import PROVIDERS

TranscribeProvider = Literal["auto", "groq", "openai"]

def is_transcribe_provider(name: str) -> bool:
    """Type guard for transcribe()'s provider argument (auto included)."""
    return isinstance(name, str) and (name == "auto" or name in PROVIDERS)

Try / catch

from agent_reach.transcribe import TranscribeError
try:
    text = transcribe(source, provider=name)
except TranscribeError as e:
    if str(e).startswith("unknown provider"):
        return transcribe(source, provider="auto")  # safe default
    raise

Prevention

When it happens

Trigger: transcribe(src, provider='azure') or a typo like 'Groq' (case-sensitive) or 'open_ai'. The check runs at line 426 immediately after the fallback-flag validation, so it fails fast with no network or ffmpeg work done.

Common situations: Forwarding user/LLM-provided provider strings without normalization; case mismatch ('OpenAI', 'GROQ'); code written against an older/newer version where the provider set differs.

Related errors


AI-assisted analysis of Panniantong/Agent-Reach@93ae1d18c3 (2026-08-14). Data as JSON: /api/errors/6d8930cc9987cba9. Report an issue: GitHub.