cocoindex-io/cocoindex · error · ValueError
An app named '{name}' is already registered in this environm
Error message
An app named '{name}' is already registered in this environment. What it means
Environment.register_app keeps a name-keyed registry of Apps per environment and rejects duplicate names under a lock. Registering a second App with the same name would make lookups ambiguous, so a ValueError is raised.
Source
Thrown at python/cocoindex/_internal/environment.py:153
__slots__ = ("_env_ref", "_app_registry", "_app_registry_lock")
_env_ref: weakref.ReferenceType[Environment | LazyEnvironment]
_app_registry: weakref.WeakValueDictionary[str, App[Any, Any]]
_app_registry_lock: threading.Lock
def __init__(self, env: Environment | LazyEnvironment) -> None:
self._env_ref = weakref.ref(env)
self._app_registry = weakref.WeakValueDictionary()
self._app_registry_lock = threading.Lock()
with _environment_info_lock:
_environment_infos.append(self)
def register_app(self, name: str, app: App[Any, Any]) -> None:
"""Register an app with this environment."""
with self._app_registry_lock:
if name in self._app_registry:
raise ValueError(
f"An app named '{name}' is already registered in this environment."
)
self._app_registry[name] = app
def get_apps(self) -> list[App[Any, Any]]:
"""Get all registered apps for this environment."""
with self._app_registry_lock:
return list(self._app_registry.values())
@property
def env(self) -> Environment | LazyEnvironment | None:
"""The environment, or None if it has been garbage collected."""
return self._env_ref()
@property
def env_name(self) -> str | None:
"""The environment name, or None if it has been garbage collected."""
env = self.envView on GitHub (pinned to e84aa99b32)
Solutions
- Use a unique app name per registration (e.g. include a timestamp or test id)
- Drop or close the existing app/environment before re-registering
- Reuse the already-registered App instead of creating a new one
- Call env.drop()/reset so the registry is cleared between runs
Example fix
# before
app = coco.App(coco.AppConfig(name="FilesTransform"), app_main)
# after (re-run-safe)
name = f"FilesTransform-{uuid.uuid4().hex[:8]}"
app = coco.App(coco.AppConfig(name=name), app_main) Defensive patterns
Strategy: validation
Validate before calling
existing = {a.name for a in env.get_apps()}
assert app_name not in existing, f"app {app_name} already registered" Try / catch
try:
env.register_app(name, app)
except ValueError:
app = env.get_apps()[[a.name for a in env.get_apps()].index(name)] # reuse existing Prevention
- Generate unique app names in notebooks/tests (uuid suffix)
- Reuse a module-level singleton App instead of re-creating it
- Tear down the environment between runs
When it happens
Trigger: Constructing and registering coco.App(AppConfig(name="X"), ...) twice in the same Environment — e.g. re-running app setup in a notebook, a script that creates the App in a loop, or module re-import without clearing the environment.
Common situations: Jupyter notebook cell re-execution, test suites building apps per test with the same name, hot-reloading dev servers that re-run module code while the environment persists.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Overriding the default lifespan function {self._lifespan_fn}
- use_mount() requires a ComponentSubpath when the function ha
- LiveComponent classes cannot be used with use_mount(). Use m
- mount() requires a ComponentSubpath when the function has no
- mount_each() requires a ComponentSubpath when the function h
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/b7d1d645c70ecd57.
Report an issue: GitHub.