{"record":{"id":"246403e2331dc699","repo":"Mintplex-Labs/anything-llm","slug":"ffmpeg-conversion-failed","errorCode":null,"errorMessage":"FFMPEG conversion failed","messagePattern":"FFMPEG conversion failed","errorType":"exception","errorClass":"Error","httpStatus":200,"severity":"error","filePath":"collector/utils/WhisperProviders/ffmpeg/index.js","lineNumber":108,"sourceCode":"      await this.ffmpegPath(),\n      [\n        \"-i\",\n        inputPath,\n        \"-ar\",\n        \"16000\",\n        \"-ac\",\n        \"1\",\n        \"-acodec\",\n        \"pcm_f32le\",\n        \"-y\",\n        outputPath,\n      ],\n      { encoding: \"utf8\" }\n    );\n\n    // ffmpeg writes progress to stderr\n    if (result.stderr) this.log(result.stderr.trim());\n    if (result.status !== 0) throw new Error(`FFMPEG conversion failed`);\n    this.log(`Conversion complete: ${path.basename(outputPath)}`);\n    return true;\n  }\n}\n\nmodule.exports = { FFMPEGWrapper };\n","sourceCodeStart":90,"sourceCodeEnd":115,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/3aec848f2885144aa8f1e53b9731a04310d5d558/collector/utils/WhisperProviders/ffmpeg/index.js#L90-L115","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before - single shot, any non-'completed' ack aborts ingest\nconst r = await client.upsert(namespace, { wait: true, batch: submission });\nif (r?.status !== 'completed') throw new Error('Error embedding into QDrant', r);\n\n// after - bounded retry for transient yellow/timeout acks\nfor (let attempt = 0; attempt < 3; attempt++) {\n  const r = await client.upsert(namespace, { wait: true, batch: submission });\n  if (r?.status === 'completed') break;\n  if (attempt === 2) throw new Error(`Upsert not completed: ${JSON.stringify(r)}`);\n  await new Promise((res) => setTimeout(res, 1000 * (attempt + 1)));\n}","handlingStrategy":"try-catch","validationCode":"// normalize the ack before trusting it: accept known-good shapes only\nfunction upsertOk(r) {\n  return r?.status === 'completed' || r?.status === 'ok';\n}\nconst r = await client.upsert(namespace, { wait: true, batch: submission });\nif (!upsertOk(r)) throw new Error(`Unexpected upsert ack: ${JSON.stringify(r)}`);","typeGuard":"function isCompletedUpsert(r) {\n  return r != null && typeof r === 'object' && r.status === 'completed';\n}","tryCatchPattern":"try {\n  await client.upsert(namespace, { wait: true, batch: submission });\n} catch (e) {\n  if (/Error embedding into QDrant/.test(e.message)) {\n    // transient yellow/timeout acks: bounded retry with backoff, then give up per-document\n    for (let i = 1; i <= 3; i++) {\n      const r = await client.upsert(namespace, { wait: true, batch: submission });\n      if (r?.status === 'completed') return;\n      await new Promise((res) => setTimeout(res, 1000 * i));\n    }\n    throw new Error('Qdrant repeatedly failed to durably acknowledge upsert');\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["qdrant","upsert","write-acknowledgment","retry","version-compatibility"],"backgroundTag":"vector-upsert-failed","analyzedSha":"3aec848f2885144aa8f1e53b9731a04310d5d558","analyzedAt":"2026-08-18T10:02:21.017Z","contentChangedAt":"2026-08-18T10:02:21.017Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}