{"record":{"id":"f3bceebf29fb89a9","repo":"n8n-io/n8n","slug":"vectorstore-this-name-requires-a-backend-se","errorCode":null,"errorMessage":"VectorStore \"${this.name}\" requires a backend — set it via .store()","messagePattern":"VectorStore \"(.+?)\" requires a backend — set it via \\.store\\(\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/vector-store.ts","lineNumber":169,"sourceCode":"\t\t\t.input(\n\t\t\t\tz.object({\n\t\t\t\t\tquery: z.string().describe('Natural language search query'),\n\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","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/vector-store.ts#L151-L187","documentation":"VectorStore.ensureBuilt() is the lazy-build gate called by search() and addDocuments() before any embedding or backend operation. It requires a backend set via .store(backend); without one there is nothing to query or upsert against. The check fires before the embedding-model check, so backend is the first missing-prerequisite surfaced.","triggerScenarios":"Calling new VectorStore('docs').embeddingModel('openai/...').search('q') (or .addDocuments(...)) without chaining .store(backend). Also triggered when .store() was called with undefined due to an uninitialized backend variable.","commonSituations":"Prototyping a store and forgetting the backend; conditionally constructing the backend (e.g. only in production) but running the store in a test env; refactoring that moves .store() out of the chain; backend variable that resolved to undefined after an async init that hadn't completed.","solutions":["Call .store(backend) with a BuiltVectorStoreBackend instance (e.g. new PgVectorStore(...)) before search/addDocuments.","Ensure the backend variable is defined before passing it to .store() — log or assert it during async init.","If using the store as a tool, .store() must still be called before the agent first invokes the tool."],"exampleFix":"// before — throws on first search\nconst store = new VectorStore('docs').embeddingModel('openai/text-embedding-3-small');\nawait store.search('query');\n\n// after\nconst backend = new PgVectorStore({ ... });\nconst store = new VectorStore('docs')\n  .store(backend)\n  .embeddingModel('openai/text-embedding-3-small');\nawait store.search('query');","handlingStrategy":"validation","validationCode":"function readyStore(name: string, backend: unknown, model: string) {\n  if (!backend) throw new Error('VectorStore requires a backend instance');\n  return new VectorStore(name).store(backend as any).embeddingModel(model);\n}","typeGuard":"function isVectorStoreBackend(value: unknown): boolean {\n  return value !== null && typeof value === 'object' && value !== undefined &&\n    typeof (value as any).query === 'function' &&\n    typeof (value as any).upsert === 'function';\n}","tryCatchPattern":null,"preventionTips":["Always chain .store(backend) in the same builder block as construction.","If backend init is async, await it before passing to .store() — never pass an unresolved promise.","Add a smoke-test that calls .search() once during app startup so a missing backend fails fast in the right environment."],"tags":["vector-store","validation","configuration","backend"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}