n8n-io/n8n · error · OperationalError

Failed to initialize Chroma collection

Error message

Failed to initialize Chroma collection

What it means

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.

Source

Thrown at packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreChromaDB/VectorStoreChromaDB.node.ts:227

					this.index = new ChromaClient(clientConfig);
				}
			}

			try {
				this.collection = await this.index.getOrCreateCollection({
					name: this.collectionName,
					...(this.collectionMetadata && { metadata: this.collectionMetadata }),
					embeddingFunction: null,
				});
			} catch (error) {
				const message = error instanceof Error ? error.message : String(error);
				throw new OperationalError(`Chroma getOrCreateCollection error: ${message}`);
			}
		}

		if (!this.collection) {
			throw new OperationalError('Failed to initialize Chroma collection');
		}

		return this.collection;
	}

	async similaritySearchVectorWithScore(
		query: number[],
		k: number,
		filter?: this['FilterType'],
	): Promise<Array<[Document, number]>> {
		// Handle the case where query might actually be a nested array which is usually the case.

		let flatQuery: number[] = [];

		if (query.length > 0 && Array.isArray(query[0])) {
			// If the first element is an array, we need to flatten
			for (const element of query) {
				if (Array.isArray(element)) {

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. 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.
  2. Pin/upgrade `chromadb` to a version known to resolve Collection objects from `getOrCreateCollection` (this node uses ExtendedChroma.imports()).
  3. Inspect server logs to see whether the getOrCreateCollection request returned 2xx with an empty body, and report the SDK/transport pair if so.
  4. As a last resort, recreate the collection name so getOrCreateCollection takes the create path rather than a degraded get path.

Example fix

// before
this.collection = await this.index.getOrCreateCollection({
  name: this.collectionName,
  embeddingFunction: null,
});
// ...
if (!this.collection) {
  throw new OperationalError('Failed to initialize Chroma collection');
}

// after: surface the raw response so the failure is diagnosable
const collection = await this.index.getOrCreateCollection({
  name: this.collectionName,
  embeddingFunction: null,
});
if (!collection) {
  throw new OperationalError(
    `Chroma getOrCreateCollection returned ${collection} for collection "${this.collectionName}"`,
  );
}
this.collection = collection;
Defensive patterns

Strategy: validation

Validate before calling

// Validate the SDK response shape right after the call instead of relying on a downstream invariant.
const collection = await this.index.getOrCreateCollection({
  name: this.collectionName,
  ...(this.collectionMetadata && { metadata: this.collectionMetadata }),
  embeddingFunction: null,
});
if (collection == null || typeof collection !== 'object') {
  throw new OperationalError(
    `Chroma getOrCreateCollection returned ${String(collection)} for "${this.collectionName}"`,
  );
}
this.collection = collection;

Type guard

// Narrow the SDK result so the invariant check becomes a type-level guarantee.
function isChromaCollection(value: unknown): value is { name: string; count: () => Promise<number> } {
  return typeof value === 'object' && value !== null
    && typeof (value as { name?: unknown }).name === 'string'
    && typeof (value as { count?: unknown }).count === 'function';
}
// usage:
if (!isChromaCollection(this.collection)) {
  throw new OperationalError('Failed to initialize Chroma collection');
}

Try / catch

// Keep the SDK call in try/catch, then validate the resolved value before storing it.
try {
  const collection = await this.index.getOrCreateCollection({ name: this.collectionName, embeddingFunction: null });
  if (!collection) throw new OperationalError('Empty Collection response');
  this.collection = collection;
} catch (error) {
  const message = error instanceof Error ? error.message : String(error);
  throw new OperationalError(`Chroma getOrCreateCollection error: ${message}`);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/727be0c4c3c3fac0. Report an issue: GitHub.