{"record":{"id":"567be8c5022c8a4a","repo":"tobi/qmd","slug":"failed-to-get-embedding-dimensions-from-first-chun","errorCode":null,"errorMessage":"Failed to get embedding dimensions from first chunk","messagePattern":"Failed to get embedding dimensions from first chunk","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/store.ts","lineNumber":2123,"sourceCode":"          });\n        }\n        expectedChunksByHash.set(doc.hash, chunks.length);\n      }\n\n      totalChunks += batchChunks.length;\n\n      if (batchChunks.length === 0) {\n        bytesProcessed += batchBytes;\n        options?.onProgress?.({ chunksEmbedded, totalChunks, bytesProcessed, totalBytes, errors: activeErrorCount(), failures: failureList() });\n        continue;\n      }\n\n      if (!vectorTableInitialized) {\n        const firstChunk = batchChunks[0]!;\n        const firstText = formatDocForEmbedding(firstChunk.text, firstChunk.title, embedModelUri);\n        const firstResult = await session.embed(firstText, { model });\n        if (!firstResult) {\n          throw new Error(\"Failed to get embedding dimensions from first chunk\");\n        }\n        store.ensureVecTable(firstResult.embedding.length);\n        vectorTableInitialized = true;\n      }\n\n      const totalBatchChunkBytes = batchChunks.reduce((sum, chunk) => sum + chunk.bytes, 0);\n      let batchChunkBytesProcessed = 0;\n\n      for (let batchStart = 0; batchStart < batchChunks.length; batchStart += BATCH_SIZE) {\n        // Abort early if session has been invalidated (e.g. max duration exceeded)\n        if (!session.isValid) {\n          const remainingChunks = batchChunks.slice(batchStart);\n          for (const chunk of remainingChunks) recordFailure(chunk, \"LLM session expired before embedding chunk\");\n          console.warn(`⚠ Session expired — skipping ${remainingChunks.length} remaining chunks`);\n          break;\n        }\n\n        // Abort early if active error rate is too high (>80% of attempted chunks failed)","sourceCodeStart":2105,"sourceCodeEnd":2141,"githubUrl":"https://github.com/tobi/qmd/blob/dbfd0b4736aeaf761d1a16ca8e424f071df8feb9/src/store.ts#L2105-L2141","documentation":"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).","triggerScenarios":"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.","commonSituations":"Embedding after the model was unloaded by the idle timer; embed returning null in CI mode; racing embed calls against model disposal.","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"],"exampleFix":"// before\nconst firstResult = await session.embed(firstText, { model }); // null → throw\n// after\nconst firstResult = await session.embed(firstText, { model });\nif (!firstResult) throw new Error('embed returned null — re-run qmd doctor / re-embed');","handlingStrategy":"retry","validationCode":"await llm.ensureGenerateModel?.(); // warm up model before batch embed","typeGuard":null,"tryCatchPattern":"try { await embedAll(); } catch (e) { if (/embedding dimensions/.test((e as Error).message)) { await llm.ensureModels(); return embedAll(); } throw e; }","preventionTips":["Run qmd doctor before first embed","Keep the model alive during long batch jobs (touchActivity)","Retry embed batches once after model reload"],"tags":["embedding","null-result","llm"],"backgroundTag":"null-return-from-library","analyzedSha":"dbfd0b4736aeaf761d1a16ca8e424f071df8feb9","analyzedAt":"2026-08-28T18:07:46.628Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}