screenpipe/screenpipe · error

mlx transcription panic (likely Metal GPU error): {}

Error message

mlx transcription panic (likely Metal GPU error): {}

What it means

The MLX (Apple Silicon) transcription engine catches panics from spawned transcription tasks via catch_unwind and records that the model likely crashed due to a Metal GPU error. The `{}` is filled with the panic message; this is raised inside `transcribe` as it retries/falls back (called by `transcribe_detailed`).

Source

Thrown at crates/screenpipe-audio/src/transcription/engine.rs:852

                    }));
                    mlx_memory::clear_cache();
                    match outcome {
                        Ok(Ok(result)) => {
                            had_success = true;
                            let text = result.text.trim().to_string();
                            if !text.is_empty() {
                                texts.push(text);
                            }
                        }
                        Ok(Err(e)) => last_err = Some(anyhow!("{}", e)),
                        Err(panic) => {
                            let msg = panic
                                .downcast_ref::<String>()
                                .map(|s| s.as_str())
                                .or_else(|| panic.downcast_ref::<&str>().copied())
                                .unwrap_or("unknown panic");
                            last_err = Some(anyhow!(
                                "mlx transcription panic (likely Metal GPU error): {}",
                                msg
                            ));
                        }
                    }
                }

                // Any successful chunk yields a (possibly partial) transcript rather
                // than discarding the whole batch. Only error if every chunk failed.
                if had_success {
                    Ok(texts.join(" "))
                } else {
                    Err(last_err.unwrap_or_else(|| anyhow!("mlx transcription produced no output")))
                }
            }

            Self::Whisper {
                state,
                languages,

View on GitHub (pinned to 4ebf712990)

Solutions

  1. Retry with a smaller model (e.g. large -> small/base) to reduce VRAM/unified-memory pressure
  2. Chunk long audio into shorter segments before transcription
  3. Close GPU-heavy apps or reboot to free Metal memory
  4. Update macOS and the mlx crates; fall back to a non-MLX (CPU/ONNX) engine if configured

Example fix

// before
let result = mlx_engine.transcribe(&audio).await?;
// after
let result = match mlx_engine.transcribe(&audio).await {
    Ok(r) => Ok(r),
    Err(e) if e.to_string().contains("Metal") => cpu_engine.transcribe(&audio).await,
    Err(e) => Err(e),
};
Defensive patterns

Strategy: fallback

Validate before calling

if audio_samples.len() > MAX_CHUNK { chunk audio before calling transcribe }

Try / catch

match engine.transcribe(audio).await { Ok(r) => r, Err(e) => fallback_engine.transcribe(audio).await? }

Prevention

When it happens

Trigger: Running Whisper-family models via MLX when the Metal device hits an out-of-memory condition, an unsupported operation, or a driver-level assert inside the mlx-rs crate.

Common situations: Long audio files exhausting GPU memory; other apps holding Metal resources; older macOS/GPU combos; model too large for available unified memory.

Related errors


AI-assisted analysis of screenpipe/screenpipe@4ebf712990 (2026-09-01). Data as JSON: /api/errors/0fe75b66f548f525. Report an issue: GitHub.