Mintplex-Labs/anything-llm · error · Error
FFMPEG conversion failed
Error message
FFMPEG conversion failed
What it means
In the cached-vectors branch, each batch is upserted with wait:true and the code requires additionResult.status === 'completed'. Qdrant acknowledges upserts with a status — 'completed' means durably applied; 'yellow'/timeouts mean not-yet-guaranteed. The throw fires on any non-completed value, including unexpected shapes (undefined or 'ok') produced by client/server version mismatches.
Solutions
- Check Qdrant server logs around the failure for WAL/optimizer pressure or rejected writes.
- Retry the embed job — transient 'yellow' acknowledgments usually complete on a second pass.
- Align @qdrant/js-client-rest with the Qdrant server version so the upsert response shape matches what the code validates.
- If it persists under bulk load, embed fewer documents concurrently or give Qdrant more RAM/disk throughput.
Example fix
// before - single shot, any non-'completed' ack aborts ingest
const r = await client.upsert(namespace, { wait: true, batch: submission });
if (r?.status !== 'completed') throw new Error('Error embedding into QDrant', r);
// after - bounded retry for transient yellow/timeout acks
for (let attempt = 0; attempt < 3; attempt++) {
const r = await client.upsert(namespace, { wait: true, batch: submission });
if (r?.status === 'completed') break;
if (attempt === 2) throw new Error(`Upsert not completed: ${JSON.stringify(r)}`);
await new Promise((res) => setTimeout(res, 1000 * (attempt + 1)));
} Defensive patterns
Strategy: try-catch
Validate before calling
// normalize the ack before trusting it: accept known-good shapes only
function upsertOk(r) {
return r?.status === 'completed' || r?.status === 'ok';
}
const r = await client.upsert(namespace, { wait: true, batch: submission });
if (!upsertOk(r)) throw new Error(`Unexpected upsert ack: ${JSON.stringify(r)}`); Type guard
function isCompletedUpsert(r) {
return r != null && typeof r === 'object' && r.status === 'completed';
} Try / catch
try {
await client.upsert(namespace, { wait: true, batch: submission });
} catch (e) {
if (/Error embedding into QDrant/.test(e.message)) {
// transient yellow/timeout acks: bounded retry with backoff, then give up per-document
for (let i = 1; i <= 3; i++) {
const r = await client.upsert(namespace, { wait: true, batch: submission });
if (r?.status === 'completed') return;
await new Promise((res) => setTimeout(res, 1000 * i));
}
throw new Error('Qdrant repeatedly failed to durably acknowledge upsert');
}
throw e;
} Prevention
- Keep @qdrant/js-client-rest and the Qdrant server on compatible versions so ack shapes stay stable.
- Size batches conservatively (the code already chunks) and avoid many parallel embed jobs on small nodes.
- Watch WAL/optimizer metrics in Qdrant for write backpressure before bulk re-embeds.
- Make re-embed idempotent (delete-then-upsert by doc id) so retrying a partially failed batch is safe.
When it happens
Trigger: Qdrant returns 'yellow' or a timeout acknowledgment under load (slow disk, WAL pressure); oversized batch payload rejected mid-flight; @qdrant/js-client-rest version whose upsert response omits the status field the code checks; network interruption between upsert and acknowledgment.
Common situations: Bulk re-embedding a large cached corpus against an undersized Qdrant instance; upgrading the Qdrant server but not the JS client (or vice versa); concurrent ingest jobs saturating the node; slow network links to Qdrant Cloud.
Related errors
- Failed to get YouTube video transcription
- Failed to fetch documents from Paperless-ngx
- Input file does not exist.
- Error embedding into ChromaDB
- Failed to fetch
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/246403e2331dc699.
Report an issue: GitHub.
Appendix: source
Thrown at collector/utils/WhisperProviders/ffmpeg/index.js:108
await this.ffmpegPath(),
[
"-i",
inputPath,
"-ar",
"16000",
"-ac",
"1",
"-acodec",
"pcm_f32le",
"-y",
outputPath,
],
{ encoding: "utf8" }
);
// ffmpeg writes progress to stderr
if (result.stderr) this.log(result.stderr.trim());
if (result.status !== 0) throw new Error(`FFMPEG conversion failed`);
this.log(`Conversion complete: ${path.basename(outputPath)}`);
return true;
}
}
module.exports = { FFMPEGWrapper };
View on GitHub (pinned to 3aec848f28)