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

  1. Run `qmd doctor` to verify model and device health, then retry the embed
  2. Ensure the embed session/model is alive (touch activity / re-ensure model) before batching
  3. 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

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


AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28). Data as JSON: /api/errors/567be8c5022c8a4a. Report an issue: GitHub.