zeroclaw-labs/zeroclaw · error

Transcription is enabled but no transcription provider regis

Error message

Transcription is enabled but no transcription provider registered successfully. Configure at least one of: [providers.transcription.<type>.<alias>], [transcription] (Groq) with api_key + api_url, [transcription.openai], [transcription.deepgram], [transcription.assemblyai], [transcription.google], or [transcription.local_whisper].

What it means

from_config_for_agent() bails when transcription is enabled and neither the legacy [transcription.*] blocks nor the typed [providers.transcription.<type>.<alias>] entries produced a single registered provider. Unlike new() (error 295), this constructor registers both families, so hitting this error means both sources were absent or invalid — invalid typed entries are skipped with the WARN 'typed transcription provider skipped (config error)' naming the config path.

Source

Thrown at crates/zeroclaw-channels/src/transcription.rs:979

        })
    }

    pub fn from_config_for_agent(config: &Config, agent_alias: Option<&str>) -> Result<Self> {
        if matches!(config.transcription.max_audio_bytes, Some(0)) {
            bail!("transcription.max_audio_bytes must be greater than zero");
        }

        let mut transcription_providers: HashMap<String, Box<dyn TranscriptionProvider>> =
            HashMap::new();

        Self::register_legacy_providers(&mut transcription_providers, &config.transcription);
        Self::register_typed_providers(
            &mut transcription_providers,
            &config.providers.transcription,
        );

        if config.transcription.enabled && transcription_providers.is_empty() {
            bail!(
                "Transcription is enabled but no transcription provider registered \
                 successfully. Configure at least one of: [providers.transcription.<type>.<alias>], \
                 [transcription] (Groq) with api_key + api_url, [transcription.openai], \
                 [transcription.deepgram], [transcription.assemblyai], [transcription.google], \
                 or [transcription.local_whisper]."
            );
        }

        let agent_transcription_provider = agent_alias
            .or_else(|| config.resolved_runtime_agent_alias())
            .and_then(|alias| config.agents.get(alias))
            .map(|a| a.transcription_provider.as_str().to_string())
            .unwrap_or_default();

        Ok(Self {
            transcription_providers,
            max_audio_bytes: config.transcription.max_audio_bytes,
            agent_transcription_provider,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add one complete provider config — legacy ([transcription] Groq api_key+api_url, [transcription.openai], ...) or typed ([providers.transcription.groq.main])
  2. Check the startup WARN logs for 'typed transcription provider skipped (config error)' — the config_path attr names the exact broken entry
  3. Verify api_key values are actually populated after secrets merging
  4. Set transcription.enabled = false if transcription is not intended

Example fix

# before
[transcription]
enabled = true
# no provider anywhere -> error

# after (typed provider)
[providers.transcription.openai.main]
api_key = "sk-..."
api_url = "https://api.openai.com/v1/audio/transcriptions"
Defensive patterns

Strategy: validation

Validate before calling

fn transcription_startup_ok(cfg: &Config) -> bool {
    !cfg.transcription.enabled || provider_config_present(cfg)
}

fn provider_config_present(cfg: &Config) -> bool {
    let t = &cfg.transcription;
    t.api_key.as_deref().is_some_and(|k| !k.is_empty())
        || t.openai.is_some() || t.deepgram.is_some() || t.assemblyai.is_some()
        || t.google.is_some() || t.local_whisper.is_some()
        || cfg.providers.transcription.iter_entries().next().is_some()
}

Prevention

When it happens

Trigger: transcription.enabled = true with no usable provider anywhere: legacy blocks missing their api_key/api_url, typed entries failing from_typed_config (bad values), or both absent. Each failed registration logs a WARN with the config path before the final empty-map bail.

Common situations: Renamed or misspelled provider block (e.g. [transcription.open_ai]); typed entry with an invalid field value skipped at startup and never noticed until the first voice note; secrets file not merged so all api_keys are empty strings.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/de956f5b4289172c. Report an issue: GitHub.