Mintplex-Labs/anything-llm · error · Error
Audio conversion failed.
Error message
Audio conversion failed.
What it means
convertAudioBufferToWav writes the buffer to the hotdir and asks the Python collector's FFMPEG wrapper (via CollectorApi.convertAudioToWav) to convert it to 16kHz mono WAV. This error means the collector answered with success:false or without a wavFilename; the collector's own reason string is used when present, and this generic message is the fallback when it is not.
Solutions
- Check the collector service is running and healthy (hit its /health endpoint) and that COLLECTOR_ENDPOINT points at it
- Confirm ffmpeg is installed inside the collector image/container (ffmpeg -version)
- Log result.reason — the collector usually names the real ffmpeg failure; surface it instead of the generic message
- Verify the extension passed matches the audio (e.g. .webm for browser recordings) and the buffer is not empty/truncated
Defensive patterns
Strategy: fallback
Validate before calling
// Fail fast if the collector is unhealthy before attempting conversion
const healthy = await new CollectorApi().online(); // collector /health probe
if (!healthy) throw new Error('Document collector is offline — cannot convert audio to WAV'); Type guard
function isConversionSuccess(result) {
return !!result && result.success === true && typeof result.wavFilename === 'string' && result.wavFilename.length > 0;
} Try / catch
try {
wavBuffer = await convertAudioBufferToWav(audioBuffer, extension);
} catch (err) {
// If the provider accepts the original format, send it unconverted
if (err.message.startsWith('Audio conversion failed') && providerAccepts(extension)) {
wavBuffer = audioBuffer;
} else {
throw err; // collector down / ffmpeg missing — surface with err.message
}
} Prevention
- Health-check the collector at startup and refuse STT conversions when it is offline
- Ensure ffmpeg exists in the collector image (assert in its Dockerfile/CI)
- Log result.reason from the collector so the real ffmpeg failure replaces the generic message
When it happens
Trigger: The collector service is down or unreachable (COLLECTOR_ENDPOINT wrong); ffmpeg is missing from the collector container; the audio buffer is corrupt or its extension does not match the actual codec, so ffmpeg cannot decode it; collector returns an error payload without a reason field.
Common situations: Collector container not started or unhealthy in Docker; base image built without ffmpeg; mic recordings (webm/opus) truncated when the user stopped recording mid-frame; stale COLLECTOR_ENDPOINT pointing at the wrong port.
Related errors
- Collector API is not online, skipping document attachment…
- Deepgram transcription failed
- Deepgram transcription failed
- Document processing API is not online. Document
- Document processing is unavailable. The collector service…
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/252851b5580bb735.
Report an issue: GitHub.
Appendix: source
Thrown at server/utils/SpeechToText/helpers.js:26
* Convert an audio buffer to a 16kHz mono WAV buffer via the collector's
* FFMPEG wrapper. Use this when the downstream STT provider (e.g. Lemonade)
* runs a whisper.cpp backend that rejects webm/opus input.
* @param {Buffer} audioBuffer - Source audio buffer.
* @param {string} extension - Source file extension including the leading dot (e.g. ".webm").
* @returns {Promise<Buffer>} The converted WAV buffer.
*/
async function convertAudioBufferToWav(audioBuffer, extension) {
let wavPath = null;
const sourceFilename = `stt-${v4()}${extension}`;
const sourcePath = path.resolve(hotdirPath, sourceFilename);
if (!isWithin(hotdirPath, sourcePath))
throw new Error("Source path is outside the hotdir.");
try {
await fs.writeFile(sourcePath, audioBuffer);
const result = await new CollectorApi().convertAudioToWav(sourceFilename);
if (!result?.success || !result?.wavFilename)
throw new Error(result?.reason || "Audio conversion failed.");
wavPath = path.resolve(hotdirPath, result.wavFilename);
return await fs.readFile(wavPath);
} finally {
await fs.rm(sourcePath, { force: true }).catch(() => {});
if (wavPath) await fs.rm(wavPath, { force: true }).catch(() => {});
}
}
module.exports = { convertAudioBufferToWav };
View on GitHub (pinned to 3aec848f28)