{"record":{"id":"5b93fbf6090c1f80","repo":"mastra-ai/mastra","slug":"vector-configuration-is-required-to-embed-texts","errorCode":null,"errorMessage":"Vector configuration is required to embed texts.","messagePattern":"Vector configuration is required to embed texts\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/workspace/search/search-engine.ts","lineNumber":701,"sourceCode":"    const { embedder } = this.#vectorConfig;\n    if (isBatchEmbedder(embedder)) {\n      const [embedding] = await embedder([text]);\n      if (!embedding) {\n        throw new Error('Batch embedder returned no embedding for input text.');\n      }\n      return embedding;\n    }\n    return embedder(text);\n  }\n\n  /**\n   * Embed many texts. Uses a single batched call (chunked by `maxBatchSize`)\n   * when the embedder is batch-capable; otherwise falls back to parallel\n   * single-text calls.\n   */\n  async #embedAll(texts: string[]): Promise<number[][]> {\n    if (!this.#vectorConfig) {\n      throw new Error('Vector configuration is required to embed texts.');\n    }\n    if (texts.length === 0) return [];\n\n    const { embedder } = this.#vectorConfig;\n\n    if (isBatchEmbedder(embedder)) {\n      // Same sanitized size the callers group by, so an unusable `maxBatchSize` can never turn\n      // this loop into a non-advancing one.\n      const max = resolveEmbedGroupSize(embedder);\n      if (texts.length <= max) {\n        return embedder(texts);\n      }\n      // Chunk by maxBatchSize and run chunks in parallel up to DEFAULT_INDEX_MANY_CONCURRENCY.\n      const results = await pMap(chunkItems(texts, max), chunk => embedder(chunk), {\n        concurrency: DEFAULT_INDEX_MANY_CONCURRENCY,\n      });\n      return results.flat();\n    }","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/workspace/search/search-engine.ts#L683-L719","documentation":"SearchEngine throws this when #embedAll is called but the engine was constructed without vector configuration (this.#vectorConfig is null/undefined). Embedding is only supported when a vectorConfig containing an embedder (and vectorStore) was supplied, since embeddings have no meaning without a target vector store. It is an internal invariant guard surfaced through the public embeddings path.","triggerScenarios":"Calling any embedding-dependent flow (e.g. upsert/index of documents via embeddings -> #embedAll) on a SearchEngine constructed without a `vector` config; passing options that omit `vector.embedder`; constructing SearchEngine for BM25-only use and then invoking an embedding code path.","commonSituations":"Developers build a keyword-only search engine and later try to index documents into it; a config object is conditionally spread so the `vector` key is dropped; env-driven config loading fails silently and passes undefined; refactors rename the config field so the engine no longer picks it up.","solutions":["Provide a `vector` configuration (with `embedder`, `vectorStore`, `indexName`) when constructing the SearchEngine if you intend to embed texts.","Verify your config-loading code actually resolves the vector settings (check env vars/flags) and that the object is spread without dropping the `vector` key.","If you only need keyword search, avoid calling embedding-dependent methods and construct/use the BM25-only path instead."],"exampleFix":"// before\nconst engine = new SearchEngine({ bm25: bm25Config });\nawait engine.upsert(docs); // throws: no vector config\n// after\nconst engine = new SearchEngine({\n  bm25: bm25Config,\n  vector: { embedder: new FastEmbed(), vectorStore: store, indexName: 'docs' },\n});\nawait engine.upsert(docs);","handlingStrategy":"validation","validationCode":"function hasVectorConfig(engineOpts) {\n  return Boolean(engineOpts?.vector?.embedder && engineOpts?.vector?.vectorStore);\n}\nif (!hasVectorConfig(opts)) throw new Error('SearchEngine requires vector config before embedding.');\nconst engine = new SearchEngine(opts);","typeGuard":"function hasVectorConfig(o) {\n  return typeof o === 'object' && o !== null && 'vector' in o &&\n    typeof o.vector === 'object' && o.vector !== null &&\n    'embedder' in o.vector && 'vectorStore' in o.vector;\n}","tryCatchPattern":"try {\n  await engine.upsert(docs);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('Vector configuration is required')) {\n    engine = new SearchEngine({ ...opts, vector: vectorConfig });\n    await engine.upsert(docs);\n  } else throw err;\n}","preventionTips":["Always pass the full config object (vector + bm25) from a single typed factory instead of conditionally spread literals.","Type the constructor options so vector config is required for embedding-capable usages (discriminated union: VectorSearchEngineOptions | KeywordSearchEngineOptions).","Assert config presence in startup/initialization code before constructing the engine.","Check env-driven config resolution logs to confirm vector settings loaded."],"tags":["configuration","vector","embedding"],"backgroundTag":"missing-vector-config","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}