n8n-io/n8n · error · NodeOperationError
Collection must be a string
Error message
Collection must be a string
What it means
Thrown as a NodeOperationError in `getVectorStoreClient` after extracting the `chromaCollection` parameter with `extractValue: true`. The parameter is expected to be a string (the collection name) but came back as something else (object, number, array, or the RLC's raw `{ mode, value }` envelope when extraction did not unwrap it).
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreChromaDB/VectorStoreChromaDB.node.ts:397
throw new NodeApiError(this.getNode(), {
message: `Failed to list ChromaDB collections: ${errorMessage}`,
});
}
},
},
},
retrieveFields,
loadFields: retrieveFields,
insertFields,
sharedFields,
async getVectorStoreClient(context, _filter, embeddings, itemIndex) {
const collection = context.getNodeParameter('chromaCollection', itemIndex, '', {
extractValue: true,
});
if (typeof collection !== 'string') {
throw new NodeOperationError(context.getNode(), 'Collection must be a string');
}
try {
const config = await getChromaLibConfig(context, collection, itemIndex);
return await ExtendedChroma.fromExistingCollection(embeddings, config);
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
throw new NodeOperationError(context.getNode(), `Error connecting to ChromaDB: ${message}`, {
itemIndex,
});
}
},
async populateVectorStore(context, embeddings, documents, itemIndex) {
const collection = context.getNodeParameter('chromaCollection', itemIndex, '', {
extractValue: true,
});
View on GitHub (pinned to 5ac6606e81)
Solutions
- Re-open the node and pick the collection from the dropdown (or type the name) so the parameter is stored as a plain string.
- If using an expression, ensure it resolves to a string (wrap with `String(...)` or `?.toString()`).
- Check the node's `typeVersion` matches the workflow's expected version; upgrade the node if prompted.
- Inspect the saved workflow JSON to confirm `chromaCollection` is a string, not an object.
Example fix
// before
const collection = context.getNodeParameter('chromaCollection', itemIndex, '', { extractValue: true });
if (typeof collection !== 'string') {
throw new NodeOperationError(context.getNode(), 'Collection must be a string');
}
// after: coerce common envelope shapes before rejecting
const raw = context.getNodeParameter('chromaCollection', itemIndex, '', { extractValue: true });
const collection =
typeof raw === 'string' ? raw
: typeof raw === 'object' && raw && typeof (raw as { value?: unknown }).value === 'string'
? (raw as { value: string }).value
: undefined;
if (!collection) {
throw new NodeOperationError(context.getNode(), 'Collection must be a string', {
description: `Received ${typeof raw}: ${JSON.stringify(raw)}`,
itemIndex,
});
} Defensive patterns
Strategy: type-guard
Validate before calling
// Resolve the parameter to a string, coercing common envelope shapes, before using it.
function resolveCollectionName(context: IExecuteFunctions, itemIndex: number): string {
const raw = context.getNodeParameter('chromaCollection', itemIndex, '', { extractValue: true });
if (typeof raw === 'string') return raw;
if (raw && typeof raw === 'object' && typeof (raw as { value?: unknown }).value === 'string') {
return (raw as { value: string }).value;
}
throw new NodeOperationError(context.getNode(), 'Collection must be a string', {
itemIndex, description: `Received ${typeof raw}: ${JSON.stringify(raw)}`,
});
} Type guard
function isCollectionName(value: unknown): value is string {
return typeof value === 'string' && value.trim().length > 0;
} Try / catch
const raw = context.getNodeParameter('chromaCollection', itemIndex, '', { extractValue: true });
if (!isCollectionName(raw)) {
throw new NodeOperationError(context.getNode(), 'Collection must be a string', { itemIndex });
}
// proceed with raw Prevention
- Always pick the collection from the dropdown so it is stored as a string.
- Wrap expression results with String(...) when binding to this field.
- Upgrade node typeVersion after a parameter-shape change.
When it happens
Trigger: The collection RLC is in 'name' mode but its stored value is not a string; a workflow JSON migrated from an older typeVersion stored the collection as an object; an expression resolved to a non-string value at execution time.
Common situations: Workflow imported from a different n8n version where the parameter shape changed; expression like `={{ $json.someObject }}` returning an object instead of a string; typeVersion downgrade where the RLC envelope isn't unwrapped.
Related errors
- Parameter ${key} must be a string
- Error connecting to ChromaDB: ${message}
- ChromaDB embedding dimension mismatch: ${displayMessage}
- Error inserting documents into ChromaDB: ${errorMessage}
- Error: No JSON string provided.
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/81ff0fbc5b680789.
Report an issue: GitHub.