{"record":{"id":"874865a02f7ad13c","repo":"Zackriya-Solutions/meetily","slug":"resample-task-panicked","errorCode":null,"errorMessage":"Resample task panicked: {}","messagePattern":"Resample task panicked: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/audio/retranscription.rs","lineNumber":225,"sourceCode":"\n    info!(\n        \"Decoded audio: {:.2}s, {}Hz, {} channels\",\n        duration_seconds, decoded.sample_rate, decoded.channels\n    );\n\n    emit_progress(&app, &meeting_id, \"decoding\", 15, \"Converting audio format...\");\n\n    // Check for cancellation\n    if RETRANSCRIPTION_CANCELLED.load(Ordering::SeqCst) {\n        return Err(anyhow!(\"Retranscription cancelled\"));\n    }\n\n    // Convert to 16kHz mono format (CPU-intensive, run in blocking task)\n    let audio_samples = tokio::task::spawn_blocking(move || {\n        decoded.to_whisper_format()\n    })\n    .await\n    .map_err(|e| anyhow!(\"Resample task panicked: {}\", e))?;\n    info!(\"Converted to 16kHz mono format: {} samples\", audio_samples.len());\n\n    emit_progress(&app, &meeting_id, \"vad\", 20, \"Detecting speech segments...\");\n\n    // Check for cancellation\n    if RETRANSCRIPTION_CANCELLED.load(Ordering::SeqCst) {\n        return Err(anyhow!(\"Retranscription cancelled\"));\n    }\n\n    // Use VAD to find natural speech boundaries (same approach as live transcription)\n    // IMPORTANT: Run VAD in a blocking task to avoid blocking the async runtime\n    // For large files (35+ minutes), VAD processing can take several minutes\n    let app_for_vad = app.clone();\n    let meeting_id_for_vad = meeting_id.clone();\n\n    let speech_segments = tokio::task::spawn_blocking(move || {\n        get_speech_chunks_with_progress(\n            &audio_samples,","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/audio/retranscription.rs#L207-L243","documentation":"DecodedAudio::to_whisper_format (conversion to 16 kHz mono) panicked inside its spawn_blocking task, surfacing as a JoinError. The resampler crashed on degenerate decoded-audio parameters - zero channels, zero/absurd sample rate, or malformed sample buffers - rather than handling them as errors.","triggerScenarios":"A file that decodes 'successfully' but to garbage metadata (0 channels or 0 Hz) after corruption; huge sample counts overflowing length arithmetic; channel/index assumptions violated by unusual layouts.","commonSituations":"Same damaged-file class as decode panics; truncated headers that parse but yield inconsistent stream parameters; files from nonstandard recorders.","solutions":["Check the preceding log line 'Decoded audio: Xs, YHz, N channels' - zero or absurd values confirm bad metadata","Repair or re-encode the source audio (e.g., ffmpeg -i in.wav out.wav) and retry","Add sanity checks in to_whisper_format so invalid channels/sample_rate return Err instead of panicking"],"exampleFix":"// before\n// to_whisper_format resamples assuming decoded metadata is valid\n\n// after - reject degenerate metadata before any resample math\nif self.channels == 0 || self.sample_rate == 0 {\n    anyhow::bail!(\n        \"invalid decoded audio: {} channels @ {} Hz - source file is corrupt\",\n        self.channels,\n        self.sample_rate\n    );\n}","handlingStrategy":"try-catch","validationCode":"// Post-decode precondition before conversion\nif decoded.channels == 0 || decoded.sample_rate == 0 || decoded.samples.is_empty() {\n    return Err(anyhow::anyhow!(\"decoded audio is degenerate ({} ch @ {} Hz) - source corrupt\", decoded.channels, decoded.sample_rate));\n}","typeGuard":null,"tryCatchPattern":"Treat the JoinError as a data problem, not a transient one: report the source file as corrupt/unsupported and offer re-encode (e.g., ffmpeg) or a different file. Do not auto-retry - the same input will panic again. Log the 'Decoded audio: ...' line for the offending file.","preventionTips":["Validate decoded metadata (channels > 0, sample_rate > 0, non-empty samples) before to_whisper_format","Convert panics to errors inside to_whisper_format instead of letting spawn_blocking surface JoinError","Keep a fixture corpus of odd-but-valid audio files in tests to catch resampler assumptions"],"tags":["panic","resampling","audio-conversion","spawn-blocking","join-error"],"backgroundTag":"blocking-task-panic","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}