tonhowtf/omniget · error · anyhow::Error

nada foi gravado (microfone/permissao?)

Error message

nada foi gravado (microfone/permissao?) {}

What it means

After stopping ffmpeg, stop() validates the WAV output: if the file is missing or smaller than 1000 bytes, nothing usable was captured. ffmpeg's captured stderr is appended to the message to explain why ('nothing was recorded — microphone/permission?').

Solutions

  1. Grant microphone permission to the app in OS privacy settings (macOS: System Settings > Privacy & Security > Microphone; Windows: Settings > Privacy > Microphone).
  2. Check the configured audio input device in the app's dictation options and select a valid, connected device.
  3. Read the appended ffmpeg stderr in the error message — it names the real capture failure (e.g. 'Device or resource busy').
  4. Verify the microphone works in another app; close other apps holding exclusive access to the device.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// Rust: verify a default input device is reachable before recording
def assert_mic_available() -> Result<(), String> {
    // enumerate input devices; error if none or permission pending
    Ok(())
}

Try / catch

match dictation::stop(progress).await {
    Err(e) if e.to_string().contains("nada foi gravado") => {
        eprintln!("mic issue: {e}"); // includes ffmpeg stderr — check device/permissions
    }
    other => other?,
}

Prevention

When it happens

Trigger: rec.wav does not exist or its length < 1000 bytes when checked right after the ffmpeg child finishes.

Common situations: Microphone not plugged in or wrong input device configured; OS privacy settings deny microphone access to the app (macOS TCC, Windows privacy); selected input device name no longer matches after hardware change; ffmpeg exited immediately due to an invalid device string.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/97d76d57c67373fe. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/dictation.rs:292

        }
        // 'q' no stdin encerra o ffmpeg fechando o WAV corretamente.
        if let Some(mut stdin) = rec.child.stdin.take() {
            use tokio::io::AsyncWriteExt;
            let _ = stdin.write_all(b"q\n").await;
            let _ = stdin.flush().await;
        }
        let status =
            tokio::time::timeout(std::time::Duration::from_secs(8), rec.child.wait()).await;
        if status.is_err() {
            let _ = rec.child.kill().await;
        }
        if !rec.wav.exists() || std::fs::metadata(&rec.wav).map(|m| m.len()).unwrap_or(0) < 1000 {
            let mut err = String::new();
            if let Some(mut e) = rec.child.stderr.take() {
                use tokio::io::AsyncReadExt;
                let _ = e.read_to_string(&mut err).await;
            }
            return Err(anyhow!(
                "nada foi gravado (microfone/permissao?) {}",
                err.trim()
            ));
        }
        let opts = options();
        let out_dir = super::temp_dir().join("dictation-out");
        let _ = std::fs::create_dir_all(&out_dir);
        let t = super::whisper::transcribe(
            super::whisper::TranscribeOptions {
                input: rec.wav.to_string_lossy().to_string(),
                model: opts.model.clone(),
                language: opts.language.clone(),
                translate: false,
                max_len: 0,
                prompt: String::new(),
                output_dir: out_dir.to_string_lossy().to_string(),
                threads: 0,
            },

View on GitHub (pinned to 8600b91f42)