Mintplex-Labs/anything-llm · error · Error
Failed to get YouTube video transcription: ${e?.message}
Error message
Failed to get YouTube video transcription: ${e?.message} What it means
Same check as the cached path, applied to freshly embedded vectors: each batch goes to client.upsert(namespace, { wait: true, ... }) and anything other than additionResult.status === 'completed' throws. Note the surrounding try/catch converts this into { vectorized: false, error } rather than a crash, so the symptom is a failed document embed in API responses/logs. Non-completed means Qdrant did not durably acknowledge the write.
Source
Thrown at collector/utils/extensions/YoutubeTranscript/YoutubeLoader/index.js:76
(module) => module.fetchTranscript
);
const transcriptSegments = await fetchTranscript(this.#videoId, {
lang: this.#language,
});
if (!transcriptSegments || transcriptSegments.length === 0)
throw new Error("Transcription not found");
transcript = this.#convertTranscriptSegmentsToText(transcriptSegments);
if (this.#addVideoInfo) {
const { Innertube } = require("youtubei.js");
const youtube = await Innertube.create();
const info = (await youtube.getBasicInfo(this.#videoId)).basic_info;
metadata.description = info.short_description;
metadata.title = info.title;
metadata.view_count = info.view_count;
metadata.author = info.author;
}
} catch (e) {
throw new Error(
`Failed to get YouTube video transcription: ${e?.message}`
);
}
return [
{
pageContent: transcript,
metadata,
},
];
}
#convertTranscriptSegmentsToText(transcriptSegments) {
return transcriptSegments
.map((segment) =>
typeof segment === "string" ? segment : segment.text || ""
)
.join(" ")
.replace(/\s+/g, " ")View on GitHub (pinned to 3aec848f28)
Solutions
- Check qdrant logs for WAL/optimizer/timeout messages at the failure timestamp.
- Retry the document embed — single-batch yellow acks usually complete on retry.
- Match @qdrant/js-client-rest to the server version so the upsert acknowledgment shape is the one expected.
- Reduce concurrency of embed jobs or lower per-batch chunk size if the node is saturated.
Example fix
// before - any non-'completed' ack marks the document failed
const additionResult = await client.upsert(namespace, { wait: true, batch });
if (additionResult?.status !== 'completed')
throw new Error('Error embedding into QDrant', additionResult);
// after - accept both durable ack spellings and retry transient ones
async function upsertCompleted(client, namespace, batch, tries = 3) {
for (let i = 0; i < tries; i++) {
const r = await client.upsert(namespace, { wait: true, batch });
if (r?.status === 'completed' || r?.status === 'ok') return r;
await new Promise((res) => setTimeout(res, 1000 * (i + 1)));
}
throw new Error(`Qdrant upsert not acknowledged: ${JSON.stringify(r)}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// addDocumentToNamespace already swallows this into { vectorized:false, error } —
// check the return value instead of awaiting a throw
const result = await vectorDB.addDocumentToNamespace(namespace, payload);
if (!result.vectorized) {
logger.warn(`Embed failed for ${payload.docId}: ${result.error}`);
scheduleRetry(payload.docId);
} Type guard
function isDurableUpsertAck(r) {
return r?.status === 'completed' || r?.status === 'ok';
} Try / catch
try {
const r = await client.upsert(namespace, { wait: true, batch });
if (!['completed', 'ok'].includes(r?.status)) throw new Error('ack not durable');
} catch (e) {
if (/Error embedding into QDrant/.test(e.message)) {
// bounded retry for transient yellow/timeout acks
for (let i = 1; i <= 3; i++) {
const r = await client.upsert(namespace, { wait: true, batch });
if (r?.status === 'completed') return;
await new Promise((res) => setTimeout(res, 1000 * i));
}
}
throw e;
} Prevention
- Always inspect the { vectorized, error } return of addDocumentToNamespace rather than assuming success.
- Match @qdrant/js-client-rest to the Qdrant server version before bulk ingest.
- Throttle concurrent embeds; Qdrant yellow acks correlate with write saturation.
- Retry failed documents idempotently (same ids upserted again).
When it happens
Trigger: Qdrant under load returns 'yellow' or times out on WAL flush; a batch larger than server limits; client/server version mismatch yielding a status field the code doesn't recognize (undefined/'ok'); transient network drop to a remote Qdrant Cloud cluster.
Common situations: Large documents split into 500-vector batches saturating a small Qdrant node; mixing old JS client with new server; shared dev instances with bursty concurrent embeds; flaky egress to cloud Qdrant.
Related errors
- FFMPEG conversion failed
- Input file ${inputPath} does not exist.
- Failed to fetch ${url}: ${response.status}
- Not a valid URL.
- Invalid link provided
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/33853379b16e1937.
Report an issue: GitHub.