BerriAI/litellm · error · Exception

cache key is None

Error message

cache key is None

What it means

Exception raised in LiteLLM's cache key generation path: after the cache-key computation the code ends up with a None cache key, which makes storing/retrieving the entry meaningless. The surrounding try/except simply re-raises, so the original 'cache key is None' message surfaces to the caller. In practice this indicates the cache-key builder could not derive a key from the given kwargs (e.g. no messages/input, or an unsupported call type).

Source

Thrown at litellm/caching/caching.py:643

                cache_key = self.get_cache_key(**kwargs)
            if cache_key is not None:
                if isinstance(result, BaseModel):
                    result = result.model_dump_json()

                ## DEFAULT TTL ##
                if self.ttl is not None:
                    kwargs["ttl"] = self.ttl
                ## Get Cache-Controls ##
                _cache_kwargs: Final = kwargs.get("cache", None)
                if isinstance(_cache_kwargs, dict):
                    for k, v in _cache_kwargs.items():
                        if k == "ttl":
                            kwargs["ttl"] = v

                cached_data: Final = {"timestamp": time.time(), "response": result}
                return cache_key, cached_data, kwargs
            else:
                raise Exception("cache key is None")
        except Exception as e:
            raise e

    def add_cache(self, result, **kwargs):
        """
        Adds a result to the cache.

        Args:
            *args: args to litellm.completion() or embedding()
            **kwargs: kwargs to litellm.completion() or embedding()

        Returns:
            None
        """
        try:
            if self.should_use_cache(**kwargs) is not True:
                return
            cache_key, cached_data, kwargs = self._add_cache_logic(result=result, **kwargs)

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Ensure the minimum inputs for the call type are present (messages for chat, input for embeddings) before the caching layer runs.
  2. If using a custom cache-key function (cache_key builder), make it always return a deterministic string.
  3. As a workaround, pass an explicit cache_key kwarg so LiteLLM skips derivation.
  4. Report the exact kwargs shape upstream if it looks like a valid call failing key derivation.

Example fix

# before
litellm.completion(model="gpt-4o", messages=None)  # cache enabled -> cache key is None

# after
litellm.completion(model="gpt-4o", messages=[{"role": "user", "content": "hi"}])
Defensive patterns

Strategy: try-catch

Validate before calling

def cache_key_precheck(call_type: str, kwargs: dict) -> None:
    if call_type in ("completion", "acompletion") and not kwargs.get("messages"):
        raise ValueError("messages required when caching is enabled")
    if call_type in ("embedding", "aembedding") and not kwargs.get("input"):
        raise ValueError("input required when caching is enabled")

Type guard

def has_cacheable_payload(kwargs: dict) -> bool:
    return bool(kwargs.get("messages") or kwargs.get("input") or kwargs.get("prompt"))

Try / catch

try:
    resp = litellm.completion(model=m, messages=msgs, caching=True)
except Exception as e:
    if "cache key is None" in str(e):
        logger.error("cache key derivation failed; retrying without cache")
        resp = litellm.completion(model=m, messages=msgs)
    else:
        raise

Prevention

When it happens

Trigger: Calling with caching enabled where the kwargs passed to the cache-key builder lack the data it hashes (no messages for completion, no input for embedding), or a call type/params combination the key builder returns None for. The None check fires on the else branch of the successful-key path.

Common situations: Enabling litellm.cache without passing messages; using a custom cache-key function that returns None for some inputs; passing None values in params that defeat key construction.

Related errors


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