{"record":{"id":"d15da87a21a2ddec","repo":"janhq/jan","slug":"failed-to-count-embedding-tokens-e-instanceof-e","errorCode":null,"errorMessage":"Failed to count embedding tokens: ${e instanceof Error ? e.message : String(e)}","messagePattern":"Failed to count embedding tokens: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/vector-db-extension/src/index.ts","lineNumber":227,"sourceCode":"      return await llm.getEmbeddingContextSize!()\n    } catch (e) {\n      throw new Error(\n        `Failed to determine embedding context size: ${e instanceof Error ? e.message : String(e)}`\n      )\n    }\n  }\n\n  private async splitChunkToFit(\n    text: string,\n    budget: number,\n    llm: { countEmbeddingTokens: (texts: string[]) => Promise<number[]> }\n  ): Promise<string[]> {\n    if (!text) return []\n    let count: number\n    try {\n      ;[count] = await llm.countEmbeddingTokens([text])\n    } catch (e) {\n      throw new Error(\n        `Failed to count embedding tokens: ${e instanceof Error ? e.message : String(e)}`\n      )\n    }\n    if (count <= budget || text.length <= MIN_CHUNK_SIZE_CHARS) return [text]\n    const mid = Math.floor(text.length / 2)\n    return [\n      ...(await this.splitChunkToFit(text.slice(0, mid), budget, llm)),\n      ...(await this.splitChunkToFit(text.slice(mid), budget, llm)),\n    ]\n  }\n\n  private getEmbeddingEngine() {\n    return window.core?.extensionManager.getByName('@janhq/llamacpp-extension') as AIEngine & {\n      embed?: (texts: string[]) => Promise<{ data: Array<{ embedding: number[]; index: number }> }>\n      getEmbeddingContextSize?: () => Promise<number | undefined>\n      countEmbeddingTokens?: (texts: string[]) => Promise<number[]>\n    }\n  }","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/extensions/vector-db-extension/src/index.ts#L209-L245","documentation":"Thrown by VectorDBExtension.splitChunkToFit() when llm.countEmbeddingTokens([text]) rejects during recursive chunk halving. Like the context-size probe, a token-count failure signals an unhealthy embedding engine; the code refuses to emit an unverified chunk that could blow past the context window. The error wraps the underlying cause.","triggerScenarios":"ensureChunksFitEmbeddingContext splits a chunk and calls countEmbeddingTokens, which rejects because the embedding server is down, the model is mid-load, or the tokenizer is unavailable.","commonSituations":"Embedding model still loading during ingestion; llamacpp extension crashed mid-batch; tokenizer files missing from the model directory.","solutions":["Confirm the embedding model is fully loaded and countEmbeddingTokens works on a sample before bulk ingestion.","Restart the llamacpp extension and retry the batch.","Ensure tokenizer files ship with the embedding model.","If the method is genuinely unavailable, the caller skips verification only when the method is absent — so update/downgrade to a version that exposes it correctly."],"exampleFix":"// before\nawait vecdbExt.ingestFile(threadId, file, opts)\n\n// after\nconst llm = (window.core?.extensionManager.getByName('@janhq/llamacpp-extension') as any)\nif (typeof llm?.countEmbeddingTokens === 'function') {\n  await llm.countEmbeddingTokens(['health check']) // throws early if unhealthy\n}\nawait vecdbExt.ingestFile(threadId, file, opts)","handlingStrategy":"try-catch","validationCode":"const llm = (window.core?.extensionManager.getByName('@janhq/llamacpp-extension') as any)\nif (typeof llm?.countEmbeddingTokens === 'function') {\n  const ok = await llm.countEmbeddingTokens(['health check']).then(() => true).catch(() => false)\n  if (!ok) { /* embedding engine unhealthy; reload */ }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await vecdbExt.ingestFile(threadId, file, opts)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Failed to count embedding tokens')) {\n    await reloadEmbeddingModel()\n    return vecdbExt.ingestFile(threadId, file, opts)\n  }\n  throw e\n}","preventionTips":["Health-check the tokenizer before ingesting large documents.","Ensure tokenizer files ship with the embedding model.","Restart llamacpp if token counting starts failing mid-session."],"tags":["vector-db","embeddings","tokenizer","chunking","llamacpp"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}