{"record":{"id":"727be0c4c3c3fac0","repo":"n8n-io/n8n","slug":"failed-to-initialize-chroma-collection","errorCode":null,"errorMessage":"Failed to initialize Chroma collection","messagePattern":"Failed to initialize Chroma collection","errorType":"exception","errorClass":"OperationalError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreChromaDB/VectorStoreChromaDB.node.ts","lineNumber":227,"sourceCode":"\n\t\t\t\t\tthis.index = new ChromaClient(clientConfig);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.collection = await this.index.getOrCreateCollection({\n\t\t\t\t\tname: this.collectionName,\n\t\t\t\t\t...(this.collectionMetadata && { metadata: this.collectionMetadata }),\n\t\t\t\t\tembeddingFunction: null,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new OperationalError(`Chroma getOrCreateCollection error: ${message}`);\n\t\t\t}\n\t\t}\n\n\t\tif (!this.collection) {\n\t\t\tthrow new OperationalError('Failed to initialize Chroma collection');\n\t\t}\n\n\t\treturn this.collection;\n\t}\n\n\tasync similaritySearchVectorWithScore(\n\t\tquery: number[],\n\t\tk: number,\n\t\tfilter?: this['FilterType'],\n\t): Promise<Array<[Document, number]>> {\n\t\t// Handle the case where query might actually be a nested array which is usually the case.\n\n\t\tlet flatQuery: number[] = [];\n\n\t\tif (query.length > 0 && Array.isArray(query[0])) {\n\t\t\t// If the first element is an array, we need to flatten\n\t\t\tfor (const element of query) {\n\t\t\t\tif (Array.isArray(element)) {","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreChromaDB/VectorStoreChromaDB.node.ts#L209-L245","documentation":"Thrown as an OperationalError after the try/catch wrapping Chroma's `getOrCreateCollection` completes without throwing. It is a defensive invariant check: `this.collection` is still falsy (null/undefined) even though the SDK returned normally. In practice the Chroma client should always either resolve to a Collection object or reject, so this fires only when an SDK version or a non-standard transport returns an empty payload that the wrapper does not recognize.","triggerScenarios":"Calling `ensureCollection()` immediately after constructing ExtendedChroma when `index.getOrCreateCollection({...})` resolves to `undefined` (e.g. a misbehaving CloudClient that returns `{}` on auth failure instead of throwing), or after a prior assignment was skipped because the constructor's client-init branch exited early.","commonSituations":"Chroma SDK version drift where the cloud client silently returns a non-Collection body on a soft 4xx; a proxy returning 200 with an empty JSON object; the `embeddingFunction: null` option being rejected by a newer SDK that returns `null` instead of throwing.","solutions":["Verify the Chroma client can reach the server with a manual `curl <url>/api/v1/heartbeat` (self-hosted) or check the Cloud tenant/database values.","Pin/upgrade `chromadb` to a version known to resolve Collection objects from `getOrCreateCollection` (this node uses ExtendedChroma.imports()).","Inspect server logs to see whether the getOrCreateCollection request returned 2xx with an empty body, and report the SDK/transport pair if so.","As a last resort, recreate the collection name so getOrCreateCollection takes the create path rather than a degraded get path."],"exampleFix":"// before\nthis.collection = await this.index.getOrCreateCollection({\n  name: this.collectionName,\n  embeddingFunction: null,\n});\n// ...\nif (!this.collection) {\n  throw new OperationalError('Failed to initialize Chroma collection');\n}\n\n// after: surface the raw response so the failure is diagnosable\nconst collection = await this.index.getOrCreateCollection({\n  name: this.collectionName,\n  embeddingFunction: null,\n});\nif (!collection) {\n  throw new OperationalError(\n    `Chroma getOrCreateCollection returned ${collection} for collection \"${this.collectionName}\"`,\n  );\n}\nthis.collection = collection;","handlingStrategy":"validation","validationCode":"// Validate the SDK response shape right after the call instead of relying on a downstream invariant.\nconst collection = await this.index.getOrCreateCollection({\n  name: this.collectionName,\n  ...(this.collectionMetadata && { metadata: this.collectionMetadata }),\n  embeddingFunction: null,\n});\nif (collection == null || typeof collection !== 'object') {\n  throw new OperationalError(\n    `Chroma getOrCreateCollection returned ${String(collection)} for \"${this.collectionName}\"`,\n  );\n}\nthis.collection = collection;","typeGuard":"// Narrow the SDK result so the invariant check becomes a type-level guarantee.\nfunction isChromaCollection(value: unknown): value is { name: string; count: () => Promise<number> } {\n  return typeof value === 'object' && value !== null\n    && typeof (value as { name?: unknown }).name === 'string'\n    && typeof (value as { count?: unknown }).count === 'function';\n}\n// usage:\nif (!isChromaCollection(this.collection)) {\n  throw new OperationalError('Failed to initialize Chroma collection');\n}","tryCatchPattern":"// Keep the SDK call in try/catch, then validate the resolved value before storing it.\ntry {\n  const collection = await this.index.getOrCreateCollection({ name: this.collectionName, embeddingFunction: null });\n  if (!collection) throw new OperationalError('Empty Collection response');\n  this.collection = collection;\n} catch (error) {\n  const message = error instanceof Error ? error.message : String(error);\n  throw new OperationalError(`Chroma getOrCreateCollection error: ${message}`);\n}","preventionTips":["Pin the chromadb SDK version so getOrCreateCollection's return shape does not drift.","Add a smoke-test in CI that constructs ExtendedChroma against a real Chroma container.","Log the raw SDK response once at debug level so silent empty-body failures are visible."],"tags":["chromadb","vector-store","invariant-check","operational-error","langchain"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}