Mintplex-Labs/anything-llm · warning · Error
Invalid audio file: ${error.message}
Error message
Invalid audio file: ${error.message} What it means
Wrapper thrown when #validateAudioFile raises (errors 25/26/27). #convertToWavAudioData catches the validation error, logs it, and re-throws with an "Invalid audio file:" prefix. This is the surfaced form of the three validation errors.
Source
Thrown at collector/utils/WhisperProviders/localWhisper.js:88
if (!fs.existsSync(outFolder))
fs.mkdirSync(outFolder, { recursive: true });
const outputFile = path.resolve(outFolder, `${v4()}.wav`);
const success = await ffmpeg.convertAudioToWav(sourcePath, outputFile);
if (!success)
throw new Error(
"[Conversion Failed]: Could not convert file to .wav format!"
);
buffer = fs.readFileSync(outputFile);
fs.rmSync(outputFile);
const wavFile = new wavefile.WaveFile(buffer);
try {
this.#validateAudioFile(wavFile);
} catch (error) {
this.#log(`Audio validation failed: ${error.message}`);
throw new Error(`Invalid audio file: ${error.message}`);
}
// Although we use ffmpeg to convert to the correct format (16k hz 32f),
// different versions of ffmpeg produce different results based on the
// environment. To ensure consistency, we convert to the correct format again.
wavFile.toBitDepth("32f");
wavFile.toSampleRate(16000);
let audioData = wavFile.getSamples();
if (Array.isArray(audioData)) {
if (audioData.length > 1) {
const SCALING_FACTOR = Math.sqrt(2);
// Merge channels into first channel to save memory
for (let i = 0; i < audioData[0].length; ++i) {
audioData[0][i] =
(SCALING_FACTOR * (audioData[0][i] + audioData[1][i])) / 2;
}View on GitHub (pinned to 526360e320)
Solutions
- Parse the inner message to determine which validation failed and act (re-encode, split, reject).
- Re-encode the source through ffmpeg to 16 kHz mono and retry.
- Split long files into <4 h chunks.
Example fix
// before
throw new Error(`Invalid audio file: ${error.message}`);
// after — typed error for programmatic handling
const err = new Error(`Invalid audio file: ${error.message}`);
err.cause = error;
err.code = error.message.includes("sample rate") ? "LOW_SAMPLE_RATE"
: error.message.includes("duration") ? "TOO_LONG" : "TOO_MANY_SAMPLES";
throw err; Defensive patterns
Strategy: try-catch
Try / catch
try { await localWhisper.processFile(filePath, name); }
catch (e) {
if (e.message.startsWith("Invalid audio file:")) {
const reason = e.message.slice("Invalid audio file:".length).trim();
/* branch on reason: re-encode, split, or reject */
}
throw e;
} Prevention
- Pre-normalize audio to 16 kHz mono before Whisper.
- Surface the inner validation reason to the user.
- Split long files upstream.
When it happens
Trigger: Any of the three validation failures (low sample rate, >4 h duration, projected samples too high) inside #convertToWavAudioData triggers the catch, which re-wraps the message.
Common situations: Bad/corrupt audio; a pre-existing WAV not normalized by ffmpeg; extremely long recordings.
Related errors
- No base URL was set.
- Audio file sample rate is too low for accurate transcription
- Audio file duration exceeds maximum limit of 4 hours.
- Audio file exceeds maximum allowed length.
- No OpenAI API key was set.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/5aef7473d6d8325b.
Report an issue: GitHub.