{"record":{"id":"37386dd2ebb2cf9d","repo":"pathwaycom/pathway","slug":"cache-name-name-used-more-than-once","errorCode":null,"errorMessage":"cache name `{name}` used more than once","messagePattern":"cache name `(.+?)` used more than once","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/udfs/caches.py","lineNumber":54,"sourceCode":"    \"\"\"On disk cache.\"\"\"\n\n    _cache: diskcache.Cache\n    _name: str | None\n    _size_limit: int\n\n    _custom_names: ClassVar[set[str]] = set()\n\n    @trace.trace_user_frame\n    def __init__(self, name: str | None = None, size_limit=2**30) -> None:\n        \"\"\"\n        Args:\n            name: name of the cache. When multiple caches have the same name, they share a storage.\n            size_limit: a memory limit of the cache in bytes.\n        \"\"\"\n        super().__init__()\n        if name is not None:\n            if name in self._custom_names:\n                raise ValueError(f\"cache name `{name}` used more than once\")\n            self._custom_names.add(name)\n        self._name = name\n        self._cache = None\n        self._size_limit = size_limit\n\n    def make_key(self, args: tuple[Any, ...], kwargs: dict[str, Any]) -> str:\n        return str(api.ref_scalar(args, tuple(kwargs.items())))\n\n    def wrap_async(self, func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:\n        @functools.wraps(func)\n        async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:\n            cache = self._get_cache(func)\n            key = self.make_key(args, kwargs)\n            if cache is None:\n                return await func(*args, **kwargs)\n            if key not in cache:\n                result = await func(*args, **kwargs)\n                cache[key] = result","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/udfs/caches.py#L36-L72","documentation":"ValueError raised by the disk-cache base class when a cache is constructed with a custom name that was already used by another cache instance in the same process. Names are global per process (tracked in a class-level set), so each custom name must be unique.","triggerScenarios":"Creating two DiskCache instances with the same name= argument, e.g. pw.udfs.DiskCache(name='my_cache') used in two @pw.udf decorators or two runs of a builder function within one Python process. Note the docstring says same-named caches share storage, but the implementation actually forbids reuse.","commonSituations":"A cache factory/helper that tags every UDF with a fixed cache name; tests that rebuild pipelines in the same interpreter; notebooks re-running cells without process restart; refactoring that instantiates the cache twice.","solutions":["Give each cache a unique name, or pass name=None to let Pathway derive the name from the function (module_qualname)","Create the cache once and reuse the single instance across UDFs that should share it","Restart the Python process after re-running pipeline construction in notebooks/tests"],"exampleFix":"// before\nc1 = pw.udfs.DiskCache(name='shared')\nc2 = pw.udfs.DiskCache(name='shared')  # ValueError\n\n// after\ncache = pw.udfs.DiskCache(name='shared')\n# reuse the same instance where sharing is intended\n@pw.udf(cache_strategy=cache)\ndef f(x: int) -> int: ...","handlingStrategy":"validation","validationCode":"from pathway.internals.udfs import caches\n\ndef unique_cache_name(name: str) -> str:\n    if name in caches.DiskCache._custom_names:\n        raise ValueError(f'cache name {name!r} already in use')\n    return name","typeGuard":null,"tryCatchPattern":"try:\n    cache = pw.udfs.DiskCache(name='shared')\nexcept ValueError as e:\n    if 'used more than once' in str(e):\n        cache = pw.udfs.DiskCache()  # fall back to derived name\n    else:\n        raise","preventionTips":["Create each named cache once and share the instance","Omit name to derive it from the function identity","Restart the interpreter between pipeline rebuilds in notebooks/tests"],"tags":["pathway","udf","cache","configuration"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}