InterviewsVector

Resolve "ChromaDB collection does not exist"

Quick answer

"Collection does not exist" in ChromaDB has two dominant causes. First, get_collection() requires the collection to already exist — use get_or_create_collection() instead, and call list_collections() to check the exact name. Second, an ephemeral client (chromadb.Client or EphemeralClient) keeps data in memory and loses it between runs, so use PersistentClient(path=...) and always reopen the exact same path you created it with.

You built a vector store, added documents, and now:

chromadb.errors.InvalidCollectionException: Collection my_docs does not exist.

Nine times out of ten this is one of two things, and they're easy to mix up. Either you asked ChromaDB to open a collection that was never created (a get_collection vs get_or_create problem), or the collection was created but never saved to disk (an ephemeral-client problem). The error message is the same for both, which is why people fix the wrong one.

This guide separates them, gives you the two one-line fixes, and then covers the subtler cause behind persistent-client failures: a path mismatch that quietly points you at an empty database.

Quick Answer

Two dominant causes. (1) get_collection() requires the collection to exist — use get_or_create_collection() and list_collections() to check the name. (2) An ephemeral client (chromadb.Client / EphemeralClient) keeps data in memory and loses it between runs — use PersistentClient(path=...) and always reopen the exact same path.

TL;DR

  • get_collection() raises if missing → use get_or_create_collection().
  • Ephemeral client = in-memory → data gone between runs; use PersistentClient(path=...).
  • Persistent but still missing? → you opened a different path. Use an absolute one.
  • Check reality with client.list_collections().
  • Names are case-sensitiveMyDocsmydocs.
  • Major version upgrade (0.4 → 0.5+) changed storage — migrate, don't just upgrade.

Which of the Two Is It?

ChromaDB collection does not exist: get_collection vs get_or_create, and ephemeral vs persistentFirst, if you call get_collection, it requires the collection to already exist — use get_or_create_collection or list the collections to check the name. If you use get_or_create, check the client: an ephemeral client keeps data in memory and loses it between runs, while a persistent client must open the exact same path used at creation.Collection <name> does not existget_collection() orget_or_create_collection()?get_collectionUse get_or_create_collection(name)or client.list_collections()to confirm the exact nameget_or_createEphemeral orPersistent client?ephemeralIn-memory — lost betweenruns. Switch toPersistentClient(path=...)persistentOpen the SAME path usedat creation (absolute);list_collections() to verify
ChromaDB collection does not exist: get_collection vs get_or_create, and ephemeral vs persistent

Answer two questions and you're done:

  1. Are you calling get_collection or get_or_create_collection? The first demands the collection already exist.
  2. Is your client ephemeral or persistent? Ephemeral never saved anything; persistent must open the same path it wrote to.

Cause 1: get_collection on Something That Isn't There

get_collection() is strict — it opens an existing collection and raises if it's missing. get_or_create_collection() opens it if present, creates it if not:

import chromadb
 
client = chromadb.PersistentClient(path="./chroma_db")
 
# ❌ raises if 'my_docs' was never created
col = client.get_collection("my_docs")
 
# ✅ opens it, or creates it on first run — never raises 'does not exist'
col = client.get_or_create_collection("my_docs")

Use get_or_create_collection unless you want a hard failure when the collection is absent. Before assuming a bug, see what's actually there:

print(client.list_collections())   # names actually in this database
🧭

Name mismatch hides here too. Collection names are case-sensitive and exact. get_collection("MyDocs") fails if you created my_docs. list_collections() shows the true names — copy from there rather than retyping.

Cause 2: An Ephemeral Client That Never Persisted

Ephemeral vs Persistent Chroma client: why the collection disappears between runsAn ephemeral client stores data in memory and loses it when the process ends or a new client starts, so the next run reports the collection does not exist. A persistent client writes to disk and survives restarts, so reopening the same path finds the collection.chromadb.Client() / EphemeralClient()Stores data in RAMLost when the process endsor a new client starts✗ 'does not exist' next runPersistentClient(path='./chroma_db')Writes SQLite to diskSurvives restartsReopen the same path✓ collection is still there
Ephemeral vs Persistent Chroma client: why the collection disappears between runs

This is the one that confuses people most: the code works within a single run, then "loses" the collection on the next run. That's because the client is in-memory.

import chromadb
 
# ❌ ephemeral — data lives in RAM, gone when the process exits
client = chromadb.Client()               # same as EphemeralClient()
client.create_collection("my_docs")      # works now...
# ...next run: Collection my_docs does not exist
 
# ✅ persistent — writes to disk, survives restarts
client = chromadb.PersistentClient(path="./chroma_db")
col = client.get_or_create_collection("my_docs")
  • chromadb.Client() / EphemeralClient() → RAM only. Great for tests, wrong for anything you reopen.
  • PersistentClient(path=...) → writes a SQLite store to disk. This is what you want for a real vector store.
⚠️

On modern ChromaDB you don't call .persist() anymore — PersistentClient writes automatically. If you're following an old tutorial that calls client.persist(), that method was removed; switching to PersistentClient is the fix, not adding the call back.

Cause 3: Persistent, but the Wrong Path

If you're already on PersistentClient and still get the error, it's almost always a path mismatch — you created the database in one place and opened another. The most common traps:

  • A relative path ("./chroma_db") resolves against the current working directory, which differs between your script, a notebook, and a cron job.
  • Two services use different paths and each sees an empty database.
  • A container mounts the volume at a different location than where data was written.

Use an absolute, single source of truth:

import os, chromadb
 
CHROMA_PATH = os.path.abspath("./chroma_db")   # pin it once
print("Chroma path:", CHROMA_PATH)
 
client = chromadb.PersistentClient(path=CHROMA_PATH)
print(client.list_collections())               # is your collection here?

If list_collections() is empty at this path, your data is somewhere else — find the directory that actually contains chroma.sqlite3 and point at it.

Framework Notes

LangChain

The LangChain Chroma wrapper has the same two levers — collection_name and persist_directory. Mismatch either and you get "does not exist":

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
 
vs = Chroma(
    collection_name="my_docs",             # must match what you created
    persist_directory="./chroma_db",       # must match the write path
    embedding_function=OpenAIEmbeddings(),
)

Create it once with Chroma.from_documents(..., persist_directory=..., collection_name=...), then reopen with the same two values. For a ValidationError from the LangChain side, see resolving LangChain ValidationError.

Client/server mode (HttpClient)

When talking to a Chroma server, the collection lives on the server, not your process. "Does not exist" here usually means you're on a different tenant or database, or the server was restarted without a persistent volume. Confirm with client.list_collections() against that server.

Version Compatibility

Chroma eraPersistenceNotes
0.3.xduckdb+parquet (legacy)Old Settings(persist_directory=...) style
0.4.xSQLite + .persist().persist() still present
0.5.x+SQLite, auto-persist.persist() removed; use PersistentClient

Crossing a major boundary changes the on-disk format. Upgrading without migrating, or pointing a new client at an old store, can make collections look missing. Pin your chromadb version and migrate deliberately.

Verification Steps

  1. list_collections() shows your collection at the path you're opening:
import chromadb
client = chromadb.PersistentClient(path="/abs/path/chroma_db")
print([c.name for c in client.list_collections()])   # ['my_docs']
  1. A get_or_create_collection + count() round-trip works after a restart:
col = client.get_or_create_collection("my_docs")
print(col.count())   # > 0 means data persisted
  1. The path you print matches everywhere the DB is opened.
  2. chroma.sqlite3 exists under that directory.
  3. In server mode, the collection appears in list_collections() against the server.

Green state: after a full restart, PersistentClient at your fixed absolute path lists the collection and count() returns your documents. That proves it truly persisted.

Prevention

  • Default to get_or_create_collection() unless you need a hard miss.
  • Use PersistentClient with an absolute path for anything you reopen.
  • Define the path and collection name as constants, imported everywhere.
  • list_collections() at startup and log what's there.
  • Keep collection_name and persist_directory identical across services.
  • Pin the chromadb version; migrate on purpose, not by accident.
  • Mount persistent volumes at a stable path in Docker/K8s.

Troubleshooting Matrix

SymptomLikely causeFix
Fails the first timeget_collection on a new nameUse get_or_create_collection
Works in-run, gone next runEphemeral clientUse PersistentClient(path=...)
Persistent but emptyWrong / relative pathUse one absolute path
Wrong name / caseTypoCopy name from list_collections()
Missing after upgradeStorage format changePin version, migrate the store
Missing in DockerVolume path mismatchMount at the same path
Missing via HttpClientWrong tenant/database or no volumeCheck server + persistence
Tutorial calls .persist()Removed APISwitch to PersistentClient

External References

FAQs

Is chromadb.Client() the same as EphemeralClient()? Yes — chromadb.Client() creates an ephemeral, in-memory client. Neither persists to disk. For anything you reopen later, use PersistentClient(path=...).

Do I still need .persist()? No. On modern Chroma, PersistentClient writes automatically. .persist() was removed; code that calls it should switch to PersistentClient rather than trying to restore the method.

Why does it work in my notebook but not my script? Usually a relative-path difference. The notebook and the script run from different working directories, so "./chroma_db" resolves to different folders. Use an absolute path in both.

Can two processes share one persistent Chroma path? For concurrent writers, run Chroma in server mode (HttpClient against a Chroma server) rather than pointing multiple PersistentClient processes at the same directory. A single persistent path is designed for one writer.

How do I recover a collection I think I lost? Point a PersistentClient at the directory containing chroma.sqlite3 and call list_collections(). If it's listed, it was a path/name issue, not data loss. If the directory has no chroma.sqlite3, the data was never persisted.

Key takeaways

  • get_collection() fails if the collection isn't there — use get_or_create_collection() to create-or-open safely.
  • An ephemeral client stores data in memory and loses it between runs; use PersistentClient(path=...) to keep it.
  • A persistent client must reopen the exact same path used at creation — a different path or working directory means an empty database.
  • Call client.list_collections() to see what actually exists and confirm the name and case.
  • Collection names are case-sensitive and exact — a typo reads as 'does not exist'.
  • Crossing a major Chroma version (0.4 to 0.5+) changed persistence; upgrading without migrating can hide old collections.

Frequently asked questions

Why does ChromaDB say my collection does not exist?

Because ChromaDB couldn't find a collection with that name in the database you're connected to. The two common reasons are calling get_collection() when it was never created, and using an ephemeral in-memory client whose data vanished between runs. Use get_or_create_collection() and a PersistentClient with a fixed path.

What's the difference between get_collection and get_or_create_collection?

get_collection() only opens an existing collection and raises if it isn't found. get_or_create_collection() opens it if it exists and creates it otherwise, so it never raises 'does not exist'. Use get_or_create_collection() unless you specifically want to fail when the collection is missing.

Why does my Chroma collection disappear between runs?

Because you used an ephemeral client — chromadb.Client() or chromadb.EphemeralClient() — which stores everything in memory. When the process ends, the data is gone. Switch to chromadb.PersistentClient(path='./chroma_db'), which writes to disk and survives restarts.

I used PersistentClient but the collection is still missing — why?

Almost always a path mismatch. You created the database at one path and opened a different one, or you ran from a different working directory so a relative path resolved elsewhere. Use an absolute path, keep it identical everywhere, and call list_collections() to confirm what's in that database.

How do I list existing ChromaDB collections?

Call client.list_collections(). It returns the collections in the database you're connected to, so you can confirm the exact name and case, and verify you're pointed at the right persistent path. If the list is empty, your data was never persisted or you're on the wrong path.

Did upgrading ChromaDB break my collections?

Possibly. Chroma changed its storage between major versions (for example 0.4 to 0.5), and the old .persist() call and legacy backends were removed. Upgrading without migrating the on-disk database, or pointing a new version at an old store, can make collections appear missing. Pin versions and migrate deliberately.

By Mohammad Wasi

Software Engineering Leader & Technical Author · Updated July 24, 2026


Related Posts