{"record":{"id":"d18b8e87d8f5395b","repo":"n8n-io/n8n","slug":"vectorstore-this-name-requires-a-description","errorCode":null,"errorMessage":"VectorStore \"${this.name}\" requires a description — set it via .description() or asTool({ description })","messagePattern":"VectorStore \"(.+?)\" requires a description — set it via \\.description\\(\\) or asTool\\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/sdk/vector-store.ts","lineNumber":134,"sourceCode":"\t/** Delete documents from the store by id. */\n\tasync deleteDocuments(ids: string[]): Promise<void> {\n\t\tif (ids.length === 0) return;\n\t\tconst { backend } = this.ensureBuilt();\n\t\tawait backend.delete({ ids });\n\t}\n\n\t/**\n\t * Expose this store as an agent tool. Pass `filterableKeys` (metadata key\n\t * -> description) to also let the model narrow results with a filter.\n\t */\n\tasTool(opts?: {\n\t\tname?: string;\n\t\tdescription?: string;\n\t\tfilterableKeys?: Record<string, string>;\n\t}): Tool {\n\t\tconst description = opts?.description ?? this.descriptionValue;\n\t\tif (!description) {\n\t\t\tthrow new Error(\n\t\t\t\t`VectorStore \"${this.name}\" requires a description — set it via .description() or asTool({ description })`,\n\t\t\t);\n\t\t}\n\n\t\tconst toolName = opts?.name ?? sanitizeToolName(`search_${this.name}`);\n\n\t\tif (!opts?.filterableKeys) {\n\t\t\treturn new Tool(toolName)\n\t\t\t\t.description(description)\n\t\t\t\t.input(z.object({ query: z.string().describe('Natural language search query') }))\n\t\t\t\t.handler(async ({ query }) => ({ results: await this.search(query) }));\n\t\t}\n\n\t\tconst filterSchema = buildFilterInputSchema(opts.filterableKeys);\n\t\treturn new Tool(toolName)\n\t\t\t.description(description)\n\t\t\t.input(\n\t\t\t\tz.object({","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/sdk/vector-store.ts#L116-L152","documentation":"VectorStore.asTool() exposes the store as an agent tool, and the tool description is what the LLM uses to decide when to call it. If neither asTool({ description }) nor a prior .description() on the store set one, the build fails — a tool without a description would be invisible or misused by the model.","triggerScenarios":"Calling new VectorStore('docs').asTool() without first calling .description('...') on the store and without passing description in the asTool options. Also hit when description is conditionally set but the condition was false.","commonSituations":"Building a store programmatically and forgetting the description; assuming the store's name doubles as the tool description; refactoring that moves .description() out of the chain.","solutions":["Call .description('Search the docs for...') on the VectorStore before .asTool().","Or pass it inline: store.asTool({ description: 'Search the docs for...' }).","Write LLM-facing descriptions: state what the store contains, when to use it, and what queries work best."],"exampleFix":"// before — throws\nconst store = new VectorStore('docs').store(backend).embeddingModel('openai/...');\nagent.tool(store.asTool());\n\n// after — set description\nconst store = new VectorStore('docs')\n  .description('Search internal product docs by semantic similarity')\n  .store(backend)\n  .embeddingModel('openai/...');\nagent.tool(store.asTool());","handlingStrategy":"validation","validationCode":"function asSearchTool(store: VectorStore, desc?: string) {\n  if (!desc || desc.trim().length === 0) {\n    throw new Error('VectorStore tool requires an LLM-facing description');\n  }\n  return store.asTool({ description: desc });\n}","typeGuard":"function hasDescription(desc: unknown): desc is string {\n  return typeof desc === 'string' && desc.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Set .description() on the VectorStore at construction time so asTool() always has one.","Write tool descriptions aimed at the LLM: what the store contains, when to search it, what queries work.","Centralize tool registration in a factory that requires a description argument."],"tags":["vector-store","as-tool","validation","llm","configuration"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}