{"record":{"id":"f2a418e13dd55348","repo":"n8n-io/n8n","slug":"vectorstore-this-name-requires-an-embedding-m","errorCode":null,"errorMessage":"VectorStore \"${this.name}\" requires an embedding model — set it via .embeddingModel()","messagePattern":"VectorStore \"(.+?)\" requires an embedding model — set it via \\.embeddingModel\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/vector-store.ts","lineNumber":172,"sourceCode":"\t\t\t\t\tfilter: filterSchema,\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.handler(async ({ query, filter }) => ({\n\t\t\t\tresults: await this.search(\n\t\t\t\t\tquery,\n\t\t\t\t\tfilter && filter.length > 0\n\t\t\t\t\t\t? { filter: { conditions: filter, combineWith: 'and' } }\n\t\t\t\t\t\t: undefined,\n\t\t\t\t),\n\t\t\t}));\n\t}\n\n\tprivate ensureBuilt(): { backend: BuiltVectorStoreBackend; embeddingModel: EmbeddingModel } {\n\t\tif (!this.backend) {\n\t\t\tthrow new Error(`VectorStore \"${this.name}\" requires a backend — set it via .store()`);\n\t\t}\n\t\tif (!this.embeddingModelValue) {\n\t\t\tthrow new Error(\n\t\t\t\t`VectorStore \"${this.name}\" requires an embedding model — set it via .embeddingModel()`,\n\t\t\t);\n\t\t}\n\t\treturn { backend: this.backend, embeddingModel: this.embeddingModelValue };\n\t}\n\n\t/** Normalizes and validates a filter; returns `undefined` for an empty one so it's never a no-op `WHERE`. */\n\tprivate resolveFilter(input?: VectorFilterInput): VectorFilter | undefined {\n\t\tif (input === undefined) return undefined;\n\t\tconst normalized = normalizeFilterInput(input);\n\t\tassertValidFilter(normalized);\n\t\treturn normalized.conditions.length > 0 ? normalized : undefined;\n\t}\n}\n\nfunction assertValidTopK(k: number): void {\n\tif (!Number.isInteger(k) || k < 1) {\n\t\tthrow new Error(`topK must be an integer >= 1, got ${k}`);","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/vector-store.ts#L154-L190","documentation":"Thrown by VectorStore.ensureBuilt() the first time you call search(), addDocuments(), or deleteDocuments(). The orchestrator needs an embedding model to convert text to/from vectors before it can talk to any backend, so it refuses to run without one. The message names the store and points at the missing builder call. Note the distinct sibling error for a missing backend (.store()).","triggerScenarios":"Calling `new VectorStore('docs').store(backend)` then immediately `await store.search('q')` or `store.addDocuments([...])` without an intervening `.embeddingModel(...)` call. Also fires when you build the VectorStore conditionally and the embeddingModel branch was skipped (e.g. an env-var guard returned early).","commonSituations":"Copy-pasting a store setup snippet and deleting the embeddingModel line; refactoring a factory function that returned the builder early; gating `.embeddingModel()` behind a feature flag that was off in the test env; wiring a backend first during local dev and forgetting the model.","solutions":["Chain `.embeddingModel('openai/text-embedding-3-small')` (or another 'provider/model' string) onto the VectorStore before any search/add/delete call.","If you already constructed an AI SDK EmbeddingModel, pass it directly: `.embeddingModel(myModel)`.","Search your setup code for `new VectorStore(` and confirm every instance has both `.store(...)` and `.embeddingModel(...)` in the chain."],"exampleFix":"// before\nconst store = new VectorStore('docs').store(new PgVectorStore('docs', opts));\nawait store.search('hello');\n\n// after\nconst store = new VectorStore('docs')\n  .store(new PgVectorStore('docs', opts))\n  .embeddingModel('openai/text-embedding-3-small');\nawait store.search('hello');","handlingStrategy":"validation","validationCode":"// Fail fast at construction time — both .store() and .embeddingModel() required.\nfunction buildVectorStore(name: string, backend: BuiltVectorStoreBackend, model: string | EmbeddingModel): VectorStore {\n  const store = new VectorStore(name).store(backend).embeddingModel(model);\n  // Force ensureBuilt() eagerly so the error throws here, not deep in a request.\n  // (ensureBuilt is private; instead, do a no-op check by asserting the chain completed:)\n  return store;\n}\n\n// Or wrap your factory so callers can't forget the model:\nfunction requireEmbeddingModel(store: VectorStore, model: string): VectorStore {\n  return store.embeddingModel(model);\n}","typeGuard":"// No type guard helps here — embeddingModelValue is private.\n// Use a builder wrapper that makes the model a required argument:\nfunction makeStore(name: string, opts: { backend: BuiltVectorStoreBackend; model: string }): VectorStore {\n  return new VectorStore(name).store(opts.backend).embeddingModel(opts.model);\n}","tryCatchPattern":"try {\n  await store.search('q');\n} catch (err) {\n  if (err instanceof Error && /requires an embedding model/.test(err.message)) {\n    // configuration bug — surface to operator, do not retry\n    throw new Error(`Misconfigured vector store: ${err.message}`);\n  }\n  throw err;\n}","preventionTips":["Treat .store() and .embeddingModel() as a required pair; lint your setup so a VectorStore is never constructed without both.","Centralize VectorStore construction in one factory that takes backend + model as required arguments.","In tests, add a smoke test that calls search() on a freshly built store to catch missing-model bugs early."],"tags":["vector-store","sdk","configuration","builder"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}