tobi/qmd · critical · Error
Failed to get embedding dimensions from first chunk
Error message
Failed to get embedding dimensions from first chunk
What it means
During the first embedding batch, session.embed() on the first chunk returned null, so the code cannot determine the vector dimensionality needed to create the vectors_vec table. This usually means the embedding context/model failed softly (returned null instead of throwing).
Source
Thrown at src/store.ts:2123
});
}
expectedChunksByHash.set(doc.hash, chunks.length);
}
totalChunks += batchChunks.length;
if (batchChunks.length === 0) {
bytesProcessed += batchBytes;
options?.onProgress?.({ chunksEmbedded, totalChunks, bytesProcessed, totalBytes, errors: activeErrorCount(), failures: failureList() });
continue;
}
if (!vectorTableInitialized) {
const firstChunk = batchChunks[0]!;
const firstText = formatDocForEmbedding(firstChunk.text, firstChunk.title, embedModelUri);
const firstResult = await session.embed(firstText, { model });
if (!firstResult) {
throw new Error("Failed to get embedding dimensions from first chunk");
}
store.ensureVecTable(firstResult.embedding.length);
vectorTableInitialized = true;
}
const totalBatchChunkBytes = batchChunks.reduce((sum, chunk) => sum + chunk.bytes, 0);
let batchChunkBytesProcessed = 0;
for (let batchStart = 0; batchStart < batchChunks.length; batchStart += BATCH_SIZE) {
// Abort early if session has been invalidated (e.g. max duration exceeded)
if (!session.isValid) {
const remainingChunks = batchChunks.slice(batchStart);
for (const chunk of remainingChunks) recordFailure(chunk, "LLM session expired before embedding chunk");
console.warn(`⚠ Session expired — skipping ${remainingChunks.length} remaining chunks`);
break;
}
// Abort early if active error rate is too high (>80% of attempted chunks failed)View on GitHub (pinned to dbfd0b4736)
Solutions
- Run `qmd doctor` to verify model and device health, then retry the embed
- Ensure the embed session/model is alive (touch activity / re-ensure model) before batching
- If it persists, delete the index and re-index from scratch
Example fix
// before
const firstResult = await session.embed(firstText, { model }); // null → throw
// after
const firstResult = await session.embed(firstText, { model });
if (!firstResult) throw new Error('embed returned null — re-run qmd doctor / re-embed'); Defensive patterns
Strategy: retry
Validate before calling
await llm.ensureGenerateModel?.(); // warm up model before batch embed
Try / catch
try { await embedAll(); } catch (e) { if (/embedding dimensions/.test((e as Error).message)) { await llm.ensureModels(); return embedAll(); } throw e; } Prevention
- Run qmd doctor before first embed
- Keep the model alive during long batch jobs (touchActivity)
- Retry embed batches once after model reload
When it happens
Trigger: Calling the store embed pipeline with an uninitialized vector table when session.embed(firstText) resolves to null — disposed model, CI mode returning null from embed, or an internal node-llama-cpp failure.
Common situations: Embedding after the model was unloaded by the idle timer; embed returning null in CI mode; racing embed calls against model disposal.
Related errors
- Failed to create any embedding context
- LLM operations are disabled in CI (set CI=true)
- Embedding dimension mismatch: existing vectors are ${existin
- ${name} must be a positive integer
- Reranker unavailable — skipping reranking (${detail}). Use -
AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28).
Data as JSON: /api/errors/567be8c5022c8a4a.
Report an issue: GitHub.