{"record":{"id":"6d8930cc9987cba9","repo":"Panniantong/Agent-Reach","slug":"unknown-provider-provider-use-groq-openai-auto","errorCode":null,"errorMessage":"unknown provider: {provider} (use groq|openai|auto)","messagePattern":"unknown provider: (.+?) \\(use groq\\|openai\\|auto\\)","errorType":"exception","errorClass":"TranscribeError","httpStatus":null,"severity":"error","filePath":"agent_reach/transcribe.py","lineNumber":402,"sourceCode":"                headers={\"Authorization\": f\"Bearer {key}\"},\n                files={\"file\": (chunk.name, fh, \"audio/m4a\")},\n                data={\"model\": info[\"model\"], \"response_format\": \"text\"},\n                timeout=timeout,\n            )\n        except requests.RequestException as e:\n            raise TranscribeError(f\"{provider}: network error: {e}\") from e\n\n    if not resp.ok:\n        raise TranscribeError(f\"{provider}: HTTP {resp.status_code}: {resp.text[:300]}\")\n    return resp.text\n\n\ndef _provider_order(provider: str) -> List[str]:\n    if provider == \"auto\":\n        return [\"groq\", \"openai\"]\n    if provider in PROVIDERS:\n        return [provider]\n    raise TranscribeError(f\"unknown provider: {provider} (use groq|openai|auto)\")\n\n\ndef transcribe(\n    source: str,\n    *,\n    provider: str = \"auto\",\n    out_dir: Optional[Path] = None,\n    config: Optional[Config] = None,\n    allow_provider_fallback: bool = False,\n) -> str:\n    \"\"\"Transcribe a URL or local file path. Returns the joined transcript text.\n\n    `provider` is one of `auto`, `groq`, or `openai`. Auto mode selects the\n    first configured provider (Groq, then OpenAI). In auto mode only, set\n    `allow_provider_fallback=True` to permit sending failed chunks to the next\n    configured provider; using the flag with an explicit provider is rejected.\n    `out_dir` defaults to a fresh temp directory; intermediate files stay there.\n    \"\"\"","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/transcribe.py#L384-L420","documentation":"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.","triggerScenarios":"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.","commonSituations":"Forwarding user/LLM-provided provider strings without normalization; case mismatch ('OpenAI', 'GROQ'); code written against an older/newer version where the provider set differs.","solutions":["Use one of 'auto', 'groq', 'openai' exactly (lowercase)","Normalize input before the call: provider = provider.strip().lower() and validate against agent_reach.transcribe.PROVIDERS | {'auto'}","Prefer provider='auto' when the caller has no strong preference — it picks the first configured provider"],"exampleFix":"# before\ntext = transcribe(url, provider=\"Groq\")  # unknown provider: Groq (use groq|openai|auto)\n\n# after\nfrom agent_reach.transcribe import PROVIDERS\nprovider = provider.strip().lower()\nif provider != \"auto\" and provider not in PROVIDERS:\n    raise ValueError(f\"provider must be auto or one of {sorted(PROVIDERS)}\")\ntext = transcribe(url, provider=provider)","handlingStrategy":"type-guard","validationCode":"from agent_reach.transcribe import PROVIDERS\n\ndef valid_transcribe_provider(name: str) -> bool:\n    return name == \"auto\" or name in PROVIDERS","typeGuard":"from typing import Literal\nfrom agent_reach.transcribe import PROVIDERS\n\nTranscribeProvider = Literal[\"auto\", \"groq\", \"openai\"]\n\ndef is_transcribe_provider(name: str) -> bool:\n    \"\"\"Type guard for transcribe()'s provider argument (auto included).\"\"\"\n    return isinstance(name, str) and (name == \"auto\" or name in PROVIDERS)","tryCatchPattern":"from agent_reach.transcribe import TranscribeError\ntry:\n    text = transcribe(source, provider=name)\nexcept TranscribeError as e:\n    if str(e).startswith(\"unknown provider\"):\n        return transcribe(source, provider=\"auto\")  # safe default\n    raise","preventionTips":["Normalize provider strings: .strip().lower() before passing","Validate against PROVIDERS plus 'auto' — never hardcode the provider list","Default to provider='auto' when the caller expresses no preference"],"tags":["validation","provider","api-misuse","transcription"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}