BerriAI/litellm · error · Exception

similarity_threshold must be provided, passed None

Error message

similarity_threshold must be provided, passed None

What it means

QdrantSemanticCache.__init__ requires similarity_threshold to be explicitly set; None is rejected because the threshold controls which cached responses count as semantic matches. There is no default value, so the constructor refuses to build a cache that could silently return unrelated cached answers. The exception is raised during construction, before any Qdrant request.

Source

Thrown at litellm/caching/qdrant_semantic_cache.py:57

        embedding_model="text-embedding-ada-002",
        host_type=None,
        vector_size=None,
    ):
        from litellm.llms.custom_httpx.http_handler import (
            _get_httpx_client,
            get_async_httpx_client,
            httpxSpecialProvider,
        )
        from litellm.secret_managers.main import get_secret_str

        if collection_name is None:
            raise Exception("collection_name must be provided, passed None")

        self.collection_name = collection_name
        print_verbose(f"qdrant semantic-cache initializing COLLECTION - {self.collection_name}")

        if similarity_threshold is None:
            raise Exception("similarity_threshold must be provided, passed None")
        self.similarity_threshold = similarity_threshold
        self.embedding_model = embedding_model
        self.vector_size = vector_size if vector_size is not None else QDRANT_VECTOR_SIZE
        headers = {}

        # check if defined as os.environ/ variable
        if qdrant_api_base:
            if isinstance(qdrant_api_base, str) and qdrant_api_base.startswith("os.environ/"):
                qdrant_api_base = get_secret_str(qdrant_api_base)
        if qdrant_api_key:
            if isinstance(qdrant_api_key, str) and qdrant_api_key.startswith("os.environ/"):
                qdrant_api_key = get_secret_str(qdrant_api_key)

        qdrant_api_base = qdrant_api_base or os.getenv("QDRANT_URL") or os.getenv("QDRANT_API_BASE")
        qdrant_api_key = qdrant_api_key or os.getenv("QDRANT_API_KEY")
        headers = {"Content-Type": "application/json"}
        if qdrant_api_key:
            headers["api-key"] = qdrant_api_key

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass similarity_threshold explicitly (typically 0.7–0.9 for cosine similarity), e.g. QdrantSemanticCache(collection_name='c', similarity_threshold=0.8, ...)
  2. Validate your cache config dict contains similarity_threshold before constructing the cache

Example fix

# before
cache = QdrantSemanticCache(collection_name='litellm-cache', qdrant_api_base=url)

# after
cache = QdrantSemanticCache(collection_name='litellm-cache', similarity_threshold=0.8, qdrant_api_base=url)
Defensive patterns

Strategy: validation

Validate before calling

def check_semantic_cfg(cfg: dict) -> None:
    if cfg.get('similarity_threshold') is None:
        raise ValueError('qdrant semantic cache requires similarity_threshold (try 0.8)')
    if not 0.0 <= float(cfg['similarity_threshold']) <= 1.0:
        raise ValueError('similarity_threshold must be within [0, 1]')

Prevention

When it happens

Trigger: Calling QdrantSemanticCache(...) without similarity_threshold, or with similarity_threshold=None explicitly; building the cache from a config mapping that omits the key.

Common situations: Copying a partial example from docs that sets collection_name but not the threshold; migrating from RedisCache (which has no such parameter) to the Qdrant semantic cache and assuming defaults exist.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/3bcedd706f560899. Report an issue: GitHub.