Skip to content

AWS Transcribe errors are silently swallowed in voice module #26

@tigy32

Description

@tigy32

Summary

When AWS Transcribe streaming fails to start or encounters an error during streaming, the error is only logged via tracing::error! and then the tokio task exits silently. Callers have no way to receive or handle these errors - they only observe symptoms like channel closures.

Location

tycode-core/src/voice/stt/aws_transcribe.rs

Problem

In the start() method, when AWS Transcribe fails:

let response = client
    .start_stream_transcription()
    // ...
    .send()
    .await;

let output = match response {
    Ok(output) => output,
    Err(e) => {
        tracing::error!("Failed to start AWS Transcribe stream: {e:?}");
        return;  // <-- Task exits silently, dropping audio_tx
    }
};

What happens:

  1. AWS Transcribe fails (auth, region, quota, invalid audio format, etc.)
  2. The tokio task logs via tracing::error! and returns
  3. This drops audio_tx, closing the audio channel
  4. The caller's audio_sink.send() starts returning errors
  5. Caller sees "send failed" but has NO visibility into the actual AWS error

The same pattern occurs for streaming errors:

while let Ok(Some(event)) = transcript_stream.recv().await {
    // ...
}
// When loop exits (stream closed or error), task exits silently
// No indication of whether this was normal completion vs error

Impact

When integrating tycode-core's voice capabilities:

  • AWS configuration errors are invisible to the application
  • Authentication failures appear as generic "channel closed" errors
  • Debugging requires adding logging inside tycode-core source
  • Applications cannot display meaningful error messages to users

Suggested Fix

  1. Propagate errors through the TranscriptionStream:
pub struct TranscriptionStream {
    rx: mpsc::Receiver<Result<TranscriptionChunk, TranscriptionError>>,
}
  1. Or add an error channel alongside the transcription channel:
async fn start(&self) -> Result<(AudioSink, TranscriptionStream, ErrorReceiver)>
  1. At minimum, surface the error when the stream ends:
pub enum TranscriptionEvent {
    Chunk(TranscriptionChunk),
    StreamEnded { error: Option<TranscriptionError> },
}

Reproduction

  1. Configure AWS Transcribe with invalid credentials or wrong region
  2. Start voice session
  3. Observe: Audio sink closes immediately with no explanation
  4. Expected: Receive error like "AWS authentication failed" or "Invalid region"

This issue also applies to the stream completion path - there's no way to distinguish between "transcription completed normally" vs "stream failed with error".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions