{"record":{"id":"cc357aa045757d75","repo":"chroma-core/chroma","slug":"the-snowballstemmer-python-package-is-not-installe","errorCode":null,"errorMessage":"The snowballstemmer python package is not installed. Please install it with `pip install snowballstemmer`","messagePattern":"The snowballstemmer python package is not installed\\. Please install it with `pip install snowballstemmer`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/utils/embedding_functions/schemas/bm25_tokenizer.py","lineNumber":205,"sourceCode":"]\n\n\nDEFAULT_CHROMA_BM25_STOPWORDS: List[str] = list(DEFAULT_ENGLISH_STOPWORDS)\n\n\nclass SnowballStemmer(Protocol):\n    def stem(self, token: str) -> str:  # pragma: no cover - protocol definition\n        ...\n\n\nclass _SnowballStemmerAdapter:\n    \"\"\"Adapter that provides the uniform `stem` API used across languages.\"\"\"\n\n    def __init__(self) -> None:\n        try:\n            import snowballstemmer\n        except ImportError:\n            raise ValueError(\n                \"The snowballstemmer python package is not installed. Please install it with `pip install snowballstemmer`\"\n            )\n\n        self._stemmer = snowballstemmer.stemmer(\"english\")\n\n    def stem(self, token: str) -> str:\n        return cast(str, self._stemmer.stemWord(token))\n\n\ndef get_english_stemmer() -> SnowballStemmer:\n    \"\"\"Return a Snowball stemmer for English.\"\"\"\n    return _SnowballStemmerAdapter()\n\n\nclass Bm25Tokenizer:\n    \"\"\"Tokenizer with stopword filtering and stemming used by BM25 embeddings.\"\"\"\n\n    def __init__(","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/utils/embedding_functions/schemas/bm25_tokenizer.py#L187-L223","documentation":"The BM25 tokenizer schema lazily creates a Snowball stemmer for English via get_english_stemmer() -> _SnowballStemmerAdapter, whose __init__ imports snowballstemmer and rewrites ImportError into this ValueError. It is an optional dependency used by BM25/sparse embedding functions for stemming during tokenization, so the failure occurs when the stemmer is first instantiated (e.g. building a BM25 embedding function configured with an English stemmer), not at chromadb import time.","triggerScenarios":"Creating a BM25-based embedding function whose tokenizer config selects the English Snowball stemmer (get_english_stemmer() path) in an environment without the package. Restoring/reloading a persisted collection whose embedding-function config includes the stemmer also re-instantiates the adapter and can trigger it on load.","commonSituations":"sparse/BM25 search added to an app whose dependency manifest only includes chromadb; CI or production images built before the BM25 feature was enabled, missing the new optional extra; teammates who ran pip install snowballstemmer manually and never committed it to requirements.","solutions":["pip install snowballstemmer in the target environment and pin it in requirements.txt/pyproject alongside chromadb.","If you don't need stemming, configure the BM25 tokenizer to use the no-stemmer option so the import path is never hit.","For reproducible deploys, add it to the Dockerfile: RUN pip install snowballstemmer.","Verify with python -c \"import snowballstemmer\" in the exact runtime (venv/container) before startup."],"exampleFix":"// before\nfrom chromadb.utils.embedding_functions.schemas.bm25_tokenizer import get_english_stemmer\nstemmer = get_english_stemmer()  # ValueError: The snowballstemmer python package is not installed...\n\n# after\n# shell: pip install snowballstemmer\nimport importlib.util\nif importlib.util.find_spec(\"snowballstemmer\") is None:\n    raise RuntimeError(\"Run: pip install snowballstemmer\")\nstemmer = get_english_stemmer()","handlingStrategy":"validation","validationCode":"import importlib.util\n\nif importlib.util.find_spec(\"snowballstemmer\") is None:\n    raise RuntimeError(\"snowballstemmer missing — run: pip install snowballstemmer (required for BM25 stemming)\")\n\nfrom chromadb.utils.embedding_functions.schemas.bm25_tokenizer import get_english_stemmer\nstemmer = get_english_stemmer()","typeGuard":"import importlib.util\n\ndef snowball_available() -> bool:\n    return importlib.util.find_spec(\"snowballstemmer\") is not None","tryCatchPattern":"try:\n    stemmer = get_english_stemmer()\nexcept ValueError as e:\n    if \"snowballstemmer\" in str(e):\n        raise RuntimeError(\"Install BM25 deps: pip install snowballstemmer\") from e\n    raise","preventionTips":["When enabling BM25/sparse search, add its optional deps to the lockfile in the same commit.","Configure the no-stemmer tokenizer option in environments where stemming is not required.","Smoke-test persisted collections after dependency changes, since loading re-instantiates the tokenizer."],"tags":["bm25","snowballstemmer","dependency","import","tokenizer","chroma"],"backgroundTag":"missing-python-dependency","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}