{"record":{"id":"5cc70414481e3e6a","repo":"apache/beam","slug":"at-least-one-owner-must-be-registered","errorCode":null,"errorMessage":"At least one owner must be registered.","messagePattern":"At least one owner must be registered\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/utils/subprocess_server.py","lineNumber":114,"sourceCode":"            \"Subprocess owner %s already purged. If this occurs during atexit \"\n            \"shutdown, the subprocess was already cleaned up earlier.\",\n            owner)\n        return\n      del self._live_owners[owner]\n      for key, entry in list(self._cache.items()):\n        if owner in entry.owners:\n          entry.owners.remove(owner)\n        if not entry.owners:\n          to_delete.append(entry.obj)\n          del self._cache[key]\n    # Actually call the destructors outside of the lock.\n    for value in to_delete:\n      self._destructor(value)\n\n  def get(self, *key, owner=None):\n    with self._lock:\n      if not self._live_owners:\n        raise RuntimeError(\"At least one owner must be registered.\")\n      if owner is not None and owner not in self._live_owners:\n        raise RuntimeError(\"The requesting owner must be registered.\")\n\n      if key not in self._cache:\n        self._cache[key] = _SharedCacheEntry(self._constructor(*key), set())\n      if owner is not None:\n        self._cache[key].owners.add(owner)\n        for live_owner, is_context in self._live_owners.items():\n          if is_context:\n            self._cache[key].owners.add(live_owner)\n      else:\n        for live_owner in self._live_owners:\n          self._cache[key].owners.add(live_owner)\n      return self._cache[key].obj\n\n  def force_remove(self, *key):\n    with self._lock:\n      entry = self._cache.pop(key, None)","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/utils/subprocess_server.py#L96-L132","documentation":"_SharedCache in apache_beam/utils/subprocess_server.py caches shared resources (e.g. subprocess servers) keyed by owner. get() requires at least one owner to have been registered via register_owner; with an empty owner set the cache cannot safely create/return entries, so it raises this RuntimeError.","triggerScenarios":"Calling cache.get(*key) (with or without owner=...) before any register_owner() call, or after all owners were unregistered (e.g. all pipelines closed and cleanup ran).","commonSituations":"Invoking subprocess server helpers outside the normal Beam pipeline lifecycle; calling get() after service shutdown/teardown; custom code constructing a _SharedCache and forgetting to register an owner.","solutions":["Register an owner first via cache.register_owner(owner) before calling get().","Pass owner=<registered owner> to get() so usage is tracked for cleanup.","Ensure teardown/unregister isn't called before the final get() in your lifecycle.","If driving Beam internals directly, create the cache within the standard Pipeline machinery so owners are registered automatically."],"exampleFix":"// before\nserver = shared_cache.get('beam', jar)  # RuntimeError\n// after\nshared_cache.register_owner('pipeline-1')\nserver = shared_cache.get('beam', jar, owner='pipeline-1')","handlingStrategy":"validation","validationCode":"if not shared_cache._live_owners:\n    raise RuntimeError('register an owner before using the shared cache')","typeGuard":"def cache_is_ready(cache) -> bool:\n    return bool(getattr(cache, '_live_owners', None))","tryCatchPattern":"try:\n    server = cache.get(key, owner=owner)\nexcept RuntimeError as e:\n    logging.error('Shared cache misuse: %s', e)\n    cache.register_owner(owner)\n    server = cache.get(key, owner=owner)\n","preventionTips":["Always call register_owner before get","Pass the owner argument to get so cleanup is tracked","Keep unregister/teardown after all cache usage","Use the cache only within the Beam pipeline lifecycle"],"tags":["python","apache-beam","subprocess-server","shared-cache","lifecycle","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}