cocoindex-io/cocoindex · error · ValueError
Context key {key} already used
Error message
Context key {key} already used What it means
ContextKey names are globally unique in a process. The constructor registers each key string in a process-wide set guarded by a lock; constructing a second ContextKey with the same string raises ValueError so that two independently-created keys can never alias the same context slot.
Source
Thrown at python/cocoindex/_internal/context_keys.py:107
running_loop_error_msg=(
f"Async state function on detect_change context key {key_name!r} "
"cannot be called from a running event loop at provide() time. "
"Use a sync state function, or provide the value outside of an "
"async context."
),
)
return [outcome.state for outcome in outcomes]
class ContextKey(Generic[T_co]):
__slots__ = ("_key", "_detect_change")
_key: str
_detect_change: bool
def __init__(self, key: str, *, detect_change: bool = False):
with _lock:
if key in _used_keys:
raise ValueError(f"Context key {key} already used")
_used_keys.add(key)
self._key = key
self._detect_change = detect_change
@property
def detect_change(self) -> bool:
return self._detect_change
@property
def key(self) -> str:
return self._key
def __coco_memo_key__(self) -> str:
return self._key
class ContextProvider:
__slots__ = (View on GitHub (pinned to e84aa99b32)
Solutions
- Define each ContextKey once at module scope and import it wherever needed
- Use a distinct, namespaced string for each key (e.g. "myapp.pg_pool")
- In tests, create the key in a fresh subprocess or pick a unique suffix per test run
Example fix
// before
key = ContextKey("db") # second definition, same string
// after
from myapp.context_keys import DB_KEY # single module-level definition Defensive patterns
Strategy: validation
Validate before calling
_seen_keys: set[str] = set()
def make_key(name: str) -> str:
if name in _seen_keys:
raise AssertionError(f"duplicate ContextKey {name}")
_seen_keys.add(name)
return name Try / catch
try:
key = ContextKey("db_pool")
except ValueError as e:
key = EXISTING_DB_KEY # reuse the module-level key
logging.warning("ContextKey reused: %s", e) Prevention
- Define all ContextKey instances once at module import time
- Namespace key strings (e.g. "myapp.db_pool")
- Avoid creating keys inside functions, loops, or per-test fixtures
When it happens
Trigger: Calling ContextKey("db_pool") (or any subclass/factory) twice at module level or in a function that runs multiple times — e.g. a module imported twice with different paths, a factory function invoked per-request, a test re-running module setup in the same process, or module reload.
Common situations: Defining the same key string in two modules; creating keys dynamically inside a loop or fixture; hot-reloading a module during development.
Related errors
- No ComponentContext available. This function must be called
- Context key '{key}': expected {t.__name__}, got {type(value)
- 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
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/e981980f6fe1e5c8.
Report an issue: GitHub.