Skip to content

Malformed f32le audio buffer permanently poisons the Whisper processing queue (later valid transcribe calls fail until restart) #3221

Description

@ajanaku1

Summary

A single malformed audio buffer sent to a loaded Whisper model doesn't just fail that one transcribe call. It poisons the model's processing queue so that every subsequent transcribe on the same model instance fails with the same error, until the provider process restarts.

Seen with @qvac/sdk@0.13.5 while feeding f32le audio to whisper-tiny. If the audio buffer's byte length isn't a multiple of 4 (as a valid f32le stream must be), the call fails with:

Failed to append data to processing queue, error: f32le buffer length must be a multiple of 4

That part is reasonable — the input was malformed. The problem is that the queue never recovers. A later, well-formed request on the same modelId throws the identical error, as though the bad bytes are still stuck in the queue.

Environment

  • @qvac/sdk 0.13.5
  • Node.js 22+ (also seen on 25)
  • macOS 14 (Darwin 24.6.0)
  • Model: WHISPER_TINY (registry), modelConfig.audio_format: "f32le"

Steps to reproduce

Save as repro-whisper-queue.mjs:

import { loadModel, transcribe, close, WHISPER_TINY } from "@qvac/sdk";
import { readFile } from "node:fs/promises";

const modelId = await loadModel({
  modelSrc: WHISPER_TINY,
  modelConfig: { audio_format: "f32le", strategy: "greedy", n_threads: 4, language: "en", no_timestamps: true },
});

// A valid f32le buffer (length is a multiple of 4). Use any 16kHz mono f32le clip.
const good = await readFile("./voice-note.f32le");

// 1. Corrupt request: length NOT a multiple of 4 → expected failure.
try {
  await transcribe({ modelId, audioChunk: good.subarray(0, good.length - 1) });
  console.log("unexpected: corrupt request succeeded");
} catch (e) {
  console.log("1) corrupt request failed as expected:", e.message);
}

// 2. Valid request on the SAME model → should succeed, but fails with the
//    same queue error until the process restarts.
try {
  const text = await transcribe({ modelId, audioChunk: good });
  console.log("2) valid request OK:", JSON.stringify(text.trim()));
} catch (e) {
  console.log("2) valid request FAILED (queue poisoned):", e.message);
}

void close();

To make a valid f32le clip from any audio file:

ffmpeg -i input.wav -f f32le -ar 16000 -ac 1 voice-note.f32le

Expected

The malformed request fails on its own. The next well-formed transcribe on the same model succeeds.

Actual

The malformed request poisons the queue. Every later transcribe on that modelId fails with "Failed to append data to processing queue, error: f32le buffer length must be a multiple of 4" until the provider restarts.

Suggested fix

Validate the audio-chunk length before appending to the processing queue and reject just that request, leaving the queue intact. A per-request InvalidAudioChunk-style error that doesn't wedge the model would make this fully recoverable.

Context

Found while extending QVAC delegation to transcribe (building a P2P inference marketplace). Related, separately-filed finding on the completion side: #3220.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions