{"record":{"id":"6994164ba4588950","repo":"jax-ml/jax","slug":"key-cannot-be-empty","errorCode":null,"errorMessage":"key cannot be empty","messagePattern":"key cannot be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/_src/lru_cache.py","lineNumber":94,"sourceCode":"      self.lock_timeout_secs = lock_timeout_secs\n\n      self.lock_path = self.path / \".lockfile\"\n      if _is_local_filesystem(path):\n        self.lock = filelock.FileLock(self.lock_path)\n      else:\n        self.lock = filelock.SoftFileLock(self.lock_path)\n\n  def get(self, key: str) -> bytes | None:\n    \"\"\"Retrieves the cached value for the given key.\n\n    Args:\n      key: The key for which the cache value is retrieved.\n\n    Returns:\n      The cached data as bytes if available; ``None`` otherwise.\n    \"\"\"\n    if not key:\n      raise ValueError(\"key cannot be empty\")\n\n    cache_path = self.path / f\"{key}{_CACHE_SUFFIX}\"\n\n    if self.eviction_enabled:\n      self.lock.acquire(timeout=self.lock_timeout_secs)\n\n    try:\n      if not cache_path.exists():\n        logger.debug(f\"Cache miss for key: {key!r}\")\n        return None\n\n      logger.debug(f\"Cache hit for key: {key!r}\")\n\n      val = cache_path.read_bytes()\n\n      if self.eviction_enabled:\n        timestamp = time.time_ns().to_bytes(8, \"little\")\n        atime_path = self.path / f\"{key}{_ATIME_SUFFIX}\"","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/_src/lru_cache.py#L76-L112","documentation":"LRUCache.get validates that the cache key is non-empty before building the cache file path; an empty (or falsy) key would map to a degenerate filename, so it raises ValueError. Keys are hashed strings naming compilation-cache entries.","triggerScenarios":"Calling cache.get('') or cache.get(None) on a jax._src.lru_cache.LRUCache; indirectly if user code computes a cache key from strings that can be empty.","commonSituations":"Custom wrappers around the compilation cache that derive keys from possibly-empty names/paths; only hit by internal or advanced users of jax._src.lru_cache.","solutions":["Ensure the key is a non-empty string (typically a hash hex digest) before calling get","If generating keys yourself, fall back to a stable hash of the empty input"],"exampleFix":"# before\nvalue = cache.get(key if key else '')\n\n# after\nvalue = cache.get(key) if key else None","handlingStrategy":"validation","validationCode":"assert isinstance(key, str) and key, 'cache key must be a non-empty string'","typeGuard":"def is_valid_key(k) -> bool:\n    return isinstance(k, str) and len(k) > 0","tryCatchPattern":null,"preventionTips":["Always derive keys from a hash of inputs","Never pass optional/None keys through to cache APIs"],"tags":["jax","lru-cache","input-validation"],"backgroundTag":"empty-string-argument","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}