Problem – “Storage class not found” when initializing a Redis vector store locally
During local development of an embedding‑retrieval service, the application crashes on start‑up with an exception similar to:
Traceback (most recent call last):
File "app.py", line 42, in <module>
vector_store = RedisVectorStore.from_documents(docs, embedding)
File ".../redis_vector_store.py", line 87, in from_documents
raise ValueError("Storage class not found")
ValueError: Storage class not found
The failure occurs before any network request reaches the Redis instance, indicating a problem in the client‑side initialization rather than a connectivity issue.
Root Cause – Missing storage‑class implementation in the local Python environment
The RedisVectorStore class (commonly provided by libraries such as LangChain or redis‑om‑python) abstracts vector storage behind a storage class interface. At runtime it resolves the concrete class via entry‑points defined in the package’s setup.cfg (or pyproject.toml) under the redis_vector_store.storage group.
- If the optional dependency that provides the storage class (e.g.,
redis-omorredis-py-cluster) is not installed, the entry‑point lookup returns an empty result. - In production Docker images the extra is usually installed with
pip install my-vector-lib[redis], but a typical localrequirements.txtmay only contain the core library, omitting the extra. - The library then raises
ValueError("Storage class not found")because it cannot import the concrete implementation.
Therefore the error is not about Redis itself; it is about the Python environment lacking the storage‑class plugin.
Debug – Step‑by‑step investigation
- Confirm the exact exception and traceback. The stack trace points to the entry‑point resolution code.
- Inspect installed packages. Run:
pip freeze | grep redis
Typical output when the extra is missing:
redis==5.0.1
langchain==0.0.250
# notice: redis-om is absent
- Check entry‑points. Use
importlib.metadatato list available storage classes:
python - <<'PY'
import importlib.metadata as md
print(list(md.entry_points().select(group="redis_vector_store.storage")))
PY
If the list is empty, the storage class is not registered.
- Verify optional dependency installation. The library documentation states that the Redis storage class lives in the
redis-ompackage and is exposed via theredisextra:
pip install langchain[redis]
# or, if using redis-om directly
pip install redis-om
- Re‑run the entry‑point query after installing. The same command from step 3 should now return an entry point such as
RedisVectorStore = redis_om.vector_store:RedisVectorStore.
Solution – Install the missing storage‑class package and adjust imports
Two common remediation paths exist:
Option A – Install the library’s Redis extra (recommended)
Update requirements.txt or your pyproject.toml to include the extra:
# requirements.txt
langchain[redis]==0.0.250
Or, if you prefer a manual install:
pip install redis-om
After installation, the entry‑point is registered and the initialization succeeds.
Option B – Bypass the entry‑point and instantiate the class directly
If you cannot modify the dependency list (e.g., in a constrained environment), import the concrete class manually:
from redis_om import get_redis_connection
from redis_om.vector_store import RedisVectorStore
redis_conn = get_redis_connection(host="localhost", port=6379, decode_responses=True)
vector_store = RedisVectorStore(redis_conn, index_name="my_vectors")
This eliminates the entry‑point lookup entirely.
Before / After comparison
| Before (failing) | After (fixed) |
|---|---|
|
|
|
|
Verify – Confirm that the vector store is operational
- Run the initialization script again. Expected output:
INFO:root:Connecting to Redis at redis://localhost:6379/0
INFO:root:RedisVectorStore initialized with index 'my_vectors'
- Insert a test document and perform a similarity search:
python - <<'PY'
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import RedisVectorStore
emb = OpenAIEmbeddings()
docs = ["Redis is an in‑memory data store."]
store = RedisVectorStore.from_documents(docs, emb, index_name="test_idx")
results = store.similarity_search("in‑memory database", k=1)
print(results)
PY
Expected result (truncated):
[Document(page_content='Redis is an in‑memory data store.', metadata={})]
- Check Redis for the created index:
redis-cli FT._LIST
# should list 'test_idx'
Prevent – Guardrails to avoid recurrence
- Pin optional extras in version control. Store the full requirement line (
langchain[redis]==0.0.250) inrequirements.txtorpyproject.toml. - CI validation. Add a test that imports
RedisVectorStoreand creates a dummy index; failures will surface missing extras early. - Dockerfile best practice. Use a multi‑stage build that runs
pip install -r requirements.txtafter copying the file, ensuring the extra is installed in every image. - Runtime sanity check. At application start‑up, log the list of registered storage classes:
import importlib.metadata as md
log.info("Registered vector store storage classes: %s",
list(md.entry_points().select(group="redis_vector_store.storage")))
If the list is empty, abort with a clear error message rather than the generic “Storage class not found”.
Related Topic Hub: Data Infrastructure Troubleshooting Hub
FAQ
- Why does the error appear only on my laptop but not in CI?
CI pipelines often install the full set of extras (e.g.,pip install .[redis]) while a localrequirements.txtmay have been generated without the extra. Ensure the local file mirrors the CI definition. - Can I use a different Redis client (e.g.,
redis-py-cluster) with the same vector store?
Yes, but you must install the corresponding extra (langchain[redis-cluster]) which registers a different storage class. The entry‑point group name remains the same, so the library will pick the appropriate implementation. - What if I need to run the vector store against a Redis Enterprise Cloud instance?
The same storage class works; just provide the cloud URL and credentials via theREDIS_URLenvironment variable. Ensure TLS support is enabled in the client library (installredis[ssl]if required). - Is there a way to debug which entry‑points are being searched?
Enable debug logging for the library (e.g.,export LOG_LEVEL=DEBUG) or insert a temporaryprint(importlib.metadata.entry_points())before the call tofrom_documentsto see the raw mapping. - My application still fails after installing the extra. What else should I check?
Verify that the Python interpreter used to run the app matches the one where the package was installed (virtualenv vs system Python). Runwhich pythonandpip show langchainto confirm they refer to the same environment.