Panniantong/Agent-Reach · error · TranscribeError

all providers failed for {chunk.name}: {last_err}

Error message

all providers failed for {chunk.name}: {last_err}

What it means

Raised by _transcribe_with_fallback when every configured provider in the rotation failed for a given chunk; the message embeds the last (most informative) underlying error. It means keys existed and requests were attempted, but each TranscribeError (HTTP failure, auth rejection, network error surfaced as TranscribeError) aborted the chain. The whole transcribe() call aborts — no partial transcript is returned.

Source

Thrown at agent_reach/transcribe.py:499

    for chunk in chunks:
        text = _transcribe_with_fallback(chunk, order, cfg)
        pieces.append(text.strip())
    return "\n".join(p for p in pieces if p)


def _transcribe_with_fallback(chunk: Path, order: List[str], config: Config) -> str:
    """Try each provider in order; return first success or raise the last error."""
    last_err: Optional[Exception] = None
    for p in order:
        if not _provider_key(p, config):
            # Skip silently — caller already validated at least one is configured.
            continue
        try:
            return transcribe_chunk(chunk, p, config=config)
        except TranscribeError as e:
            last_err = e
            continue
    raise TranscribeError(f"all providers failed for {chunk.name}: {last_err}")

View on GitHub (pinned to 93ae1d18c3)

Solutions

  1. Read the embedded {last_err} in the message — it is the actual provider error and dictates the fix (401 → new key, 429 → back off, timeout → network)
  2. Run `python -m agent_reach.cli doctor` to verify key validity and connectivity
  3. Configure both groq_api_key and openai_api_key with allow_provider_fallback=True so one provider's outage does not kill the job
  4. Retry with backoff for transient 429/5xx failures

Example fix

# before
text = transcribe(url)  # all providers failed for chunk-00.mp3: 401 Unauthorized

# after — rotate key + opt into fallback
from agent_reach.transcribe import transcribe, TranscribeError
try:
    text = transcribe(url, provider="auto", allow_provider_fallback=True)
except TranscribeError as e:
    if "401" in str(e):
        refresh_keys()  # then retry once
    raise
Defensive patterns

Strategy: retry

Validate before calling

# Validate keys resolve and endpoints are reachable before the long pipeline
from agent_reach.transcribe import transcribe_chunk
from agent_reach.config import Config
import tempfile, pathlib

def probe_provider(provider: str) -> bool:
    with tempfile.TemporaryDirectory() as d:
        tiny = pathlib.Path(d) / "probe.wav"
        tiny.write_bytes(_ONE_SECOND_SILENCE_WAV)  # pre-made fixture
        try:
            transcribe_chunk(tiny, provider, config=Config())
            return True
        except Exception:
            return False

Try / catch

from agent_reach.transcribe import transcribe, TranscribeError
import time
for attempt in range(3):
    try:
        text = transcribe(url, provider="auto", allow_provider_fallback=True)
        break
    except TranscribeError as e:
        msg = str(e)
        if "401" in msg or "Unauthorized" in msg:
            raise  # auth: retrying is useless, fix the key
        if attempt == 2:
            raise
        time.sleep(2 ** attempt)  # 429/5xx/network: back off and retry

Prevention

When it happens

Trigger: transcribe() with provider='auto' and allow_provider_fallback=True where both the Groq and OpenAI upload fail (invalid/expired key → 401, rate limit → 429, oversized multipart, network timeout). Also with a single configured provider: one failure immediately becomes 'all providers failed'.

Common situations: Expired or revoked API key; hitting Groq rate limits on whisper-large-v3; flaky egress network; provider outage; key configured for the wrong environment (test key against prod endpoint).

Related errors


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