Chroma metadata error

Describe the problem/error/question

I’m trying to add documents to a Chroma vector store but it throws an error about incorrect type for metadata. The metadata seems to be set by the Default Data Loader node but contains nested object. Not somehting that is expected by Chroma and I see no way on how to remove or edit it. Is there any way to fix this?
The error is: Error inserting documents into ChromaDB: Expected metadata to be a string, number, boolean, SparseVector, or nullable

What is the error message (if any)?

Please share your workflow

Share the output returned by the last node

Error inserting documents into ChromaDB: Expected metadata to be a string, number, boolean, SparseVector, or nullable

Information on your n8n setup

  • n8n version:
  • Database (default: SQLite):
  • n8n EXECUTIONS_PROCESS setting (default: own, main):
  • Running n8n via (Docker, npm, n8n cloud, desktop app):
  • Operating system:

Thanx for the reply. I tried that but did not succeed. I switched to Qdrant as vector store and have no issues with that. Seems Chroma does not play nice with the Default Data Loader node.

Good call on switching to Qdrant. Chroma is notoriously strict about requiring perfectly flat metadata (only primitives, no nested JSON), which makes it a huge headache to use with standard data loaders that pass complex objects. Qdrant is way more forgiving with nested structures.

Sometimes it’s just better to swap the tool than spend hours fighting a Code node trying to flatten objects just to make the DB happy. Good luck with the rest of the RAG pipeline!

The error means ChromaDB received nested objects inside the document metadata. ChromaDB only allows flat values: string, number, boolean, null, or SparseVector — no nested objects or arrays.

Why it happens

The Default Data Loader copies your input item’s JSON fields into the LangChain Document.metadata. If any field contains a nested object (common with PDFs, where loaders add { loc: { pageNumber: 1 }, pdf: { info: {...} } }), ChromaDB rejects the whole batch.

Fix: flatten metadata with a Code node

Add a Code node before the Default Data Loader in your workflow and paste this:

function flattenObj(obj, prefix = '') {
  return Object.entries(obj).reduce((acc, [k, v]) => {
    const key = prefix ? `${prefix}.${k}` : k;
    if (v !== null && typeof v === 'object' && !Array.isArray(v)) {
      Object.assign(acc, flattenObj(v, key));
    } else {
      acc[key] = Array.isArray(v) ? JSON.stringify(v) : v;
    }
    return acc;
  }, {});
}

return $input.all().map(item => {
  item.json = flattenObj(item.json);
  return item;
});

This converts deep structures like { pdf: { page: 1 } } into flat keys like pdf.page: 1, which ChromaDB accepts.

Alternative: drop metadata you don’t need

If you don’t need the auto-generated loader metadata at all, use a Set node (Edit Fields → “Keep Only Set Fields” mode) right before the Default Data Loader and include only the fields you want (e.g., filename, url). Fewer fields = less chance of nested objects slipping through.

Workflow order

Data Source → [Code node / Set node] → Default Data Loader → Chroma Vector Store (Insert)
                                                ↑
                                           Embeddings model

Docs reference: Chroma Vector Store node documentation | n8n Docs

If this solved your problem, mark this answer as the solution so it doesn’t appear to other users, thus preventing the question from remaining open in the community, and press the heart button. Take care and have much success!