Skip to content

TextDecoder.decodeText force-unwraps cause crashes during repeated live transcription #414

@yw5aj

Description

@yw5aj

Summary

TextDecoder.decodeText contains force-unwraps that crash the app during repeated rapid transcription calls (e.g., live transcription preview that re-transcribes every ~200ms).

Crash Stack

EXC_BREAKPOINT / SIGTRAP
_assertionFailure → TextDecoder.decodeText(from:using:sampler:options:callback:)
→ TranscribeTask.run → WhisperKit.transcribe → WhisperKit.transcribe(audioPath:)

Root Cause

Two force-unwraps in TextDecoder.decodeText (TextDecoder.swift):

  1. Line 747: decoderInputs.initialPrompt.last! — crashes if initialPrompt is empty
  2. Line 829: decoderOutput.logits! — crashes if logits is nil

These are fine for single-shot transcription but become problematic during sustained rapid calls where internal state can degrade.

Reproduction

  • Create two WhisperKit instances (main + live)
  • Call transcribe(audioPath:) on the live instance in a tight loop (~5-10 calls/sec) during recording
  • After extended use (minutes to hours), the decoder state accumulates corruption and one of the force-unwraps hits nil

Environment

  • WhisperKit v0.15.0
  • macOS 26.2, Apple Silicon
  • Model: openai_whisper-small
  • Using separate WhisperKit instances for main and live transcription

Suggested Fix

Replace the force-unwraps with guard statements that throw errors instead of crashing:

// Line 747
guard let firstToken = decoderInputs.initialPrompt.last else {
    throw WhisperError.decodingFailed("initialPrompt is empty")
}
var nextToken: Int = firstToken

// Line 829
guard let logits = decoderOutput.logits else {
    throw WhisperError.decodingLogitsFailed("Logits output is nil")
}

This would allow callers to handle the error gracefully instead of crashing the entire app.

Related

I noticed #413 and #412 are addressing thread safety — this may be related to the same class of issues.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions