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

  1. Check Qdrant server logs around the failure for WAL/optimizer pressure or rejected writes.
  2. Retry the embed job — transient 'yellow' acknowledgments usually complete on a second pass.
  3. Align @qdrant/js-client-rest with the Qdrant server version so the upsert response shape matches what the code validates.
  4. 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

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


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)