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

  1. Re-open the node and pick the collection from the dropdown (or type the name) so the parameter is stored as a plain string.
  2. If using an expression, ensure it resolves to a string (wrap with `String(...)` or `?.toString()`).
  3. Check the node's `typeVersion` matches the workflow's expected version; upgrade the node if prompted.
  4. 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

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


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