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
- 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.
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
- 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.
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
- Chroma getOrCreateCollection error: ${message}
- Cannot connect to ChromaDB. Please ensure ChromaDB is runnin
- Authentication failed. Please check your API key or token in
- Failed to list ChromaDB collections: ${errorMessage}
- Collection must be a string
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/727be0c4c3c3fac0.
Report an issue: GitHub.