{"record":{"id":"a7b0949f93df0905","repo":"n8n-io/n8n","slug":"invalid-qdrant-point-id-id-qdrant-requires-i","errorCode":null,"errorMessage":"Invalid Qdrant point id \"${id}\": Qdrant requires ids to be a UUID or a canonical unsigned integer.","messagePattern":"Invalid Qdrant point id \"(.+?)\": Qdrant requires ids to be a UUID or a canonical unsigned integer\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/vector-stores/qdrant.ts","lineNumber":131,"sourceCode":"\t\tif (!this.client) {\n\t\t\tconst { QdrantClient: QdrantClientCtor } = await import('@qdrant/js-client-rest');\n\t\t\tthis.client = new QdrantClientCtor({\n\t\t\t\turl: this.constructorOptions.url,\n\t\t\t\tapiKey: this.constructorOptions.apiKey,\n\t\t\t});\n\t\t}\n\t\treturn this.client;\n\t}\n}\n\n/** Qdrant only accepts UUID or unsigned-integer point ids. */\nfunction toPointId(id: string): string | number {\n\tif (UUID_PATTERN.test(id)) return id;\n\tconst numeric = Number(id);\n\tif (UNSIGNED_INT_PATTERN.test(id) && Number.isSafeInteger(numeric) && String(numeric) === id) {\n\t\treturn numeric;\n\t}\n\tthrow new Error(\n\t\t`Invalid Qdrant point id \"${id}\": Qdrant requires ids to be a UUID or a canonical unsigned integer.`,\n\t);\n}\n\nfunction toQueryResult(point: Schemas['ScoredPoint']): VectorQueryResult {\n\tconst payload = (point.payload ?? {}) as unknown as QdrantPayload;\n\treturn {\n\t\tid: String(point.id),\n\t\tcontent: payload.content,\n\t\tmetadata: payload.metadata ?? {},\n\t\tscore: point.score,\n\t};\n}\n\n/** Negations are expressed as nested `must_not` filters so both `and`/`or` combinators work uniformly. */\nfunction buildQdrantFilter(filter: VectorFilter): Schemas['Filter'] {\n\tconst conditions = filter.conditions.map(buildCondition);\n\treturn filter.combineWith === 'or' ? { should: conditions } : { must: conditions };","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/vector-stores/qdrant.ts#L113-L149","documentation":"Thrown by toPointId in the Qdrant backend when a record id is neither a UUID (hyphenated, simple, urn, or braced forms accepted, matching Qdrant's Rust parser) nor a canonical unsigned integer. Qdrant rejects arbitrary string ids with a 400, so this validates first and surfaces a clear message. Note: VectorStore.addDocuments generates UUIDs via crypto.randomUUID() by default, so this only fires when the caller supplies a custom doc.id.","triggerScenarios":"Upserting a VectorDocument with `id: 'user_123'`, `id: 'doc:abc'`, `id: '-5'`, `id: '3.0'` (non-canonical), or `id: '0123'` (leading zero — fails the `String(numeric) === id` canonical check); deleting by such ids.","commonSituations":"Using business-domain string ids (slugs, SKUs, composite keys) instead of UUIDs; migrating ids from another store; integer ids with leading zeros or signs; truncating/padding ids.","solutions":["Let VectorStore.addDocuments auto-generate UUIDs (omit doc.id) — recommended for Qdrant.","If you need stable ids, generate and store UUIDs (crypto.randomUUID()) and use those as the canonical id everywhere.","For numeric ids, pass a canonical unsigned integer string with no leading zeros or sign (e.g. '5', not '05' or '+5').","If you must keep opaque string ids, choose a different backend (PgVectorStore/SupabaseVectorStore accept arbitrary text ids)."],"exampleFix":"// before — Qdrant rejects the custom slug id\nawait store.addDocuments([{ id: 'user_123', content: 'doc', metadata: {} }]);\n\n// after — let the store mint UUIDs, keep your slug in metadata\nawait store.addDocuments([{ content: 'doc', metadata: { slug: 'user_123' } }]);","handlingStrategy":"validation","validationCode":"const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nconst UINT = /^\\d+$/;\n\nfunction isQdrantSafeId(id: string): boolean {\n  if (UUID.test(id)) return true;\n  const n = Number(id);\n  return UINT.test(id) && Number.isSafeInteger(n) && String(n) === id;\n}\n\nif (doc.id && !isQdrantSafeId(doc.id)) {\n  throw new Error(`Refusing id \"${doc.id}\" for Qdrant; use a UUID or unsigned int`);\n}","typeGuard":"function isQdrantId(id: string): boolean {\n  return isQdrantSafeId(id); // see validationCode\n}","tryCatchPattern":null,"preventionTips":["For Qdrant, let VectorStore.addDocuments mint UUIDs (omit doc.id) — UUIDs are always accepted.","If you need stable ids, generate and persist UUIDs and use them as the canonical id everywhere.","If you must keep opaque string ids, choose PgVectorStore or SupabaseVectorStore, which accept arbitrary text ids."],"tags":["qdrant","validation","ids","vector-store"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}