headroomlabs-ai/headroom · error · ValueError
compressor {name!r} is already registered
Error message
compressor {name!r} is already registered What it means
Raised by CompressorRegistry.register when the name is already present and replace=False (the default). The registry deliberately makes double registration loud — two compressors under one name would silently change routing — so the second registration is refused unless the caller explicitly opts in with replace=True.
Source
Thrown at headroom/transforms/compressor_registry.py:186
"""Register ``compressor`` under its ``descriptor.name``.
Args:
compressor: The compressor to register.
replace: If ``True``, replace an existing registration of the same
name instead of raising.
Returns:
The registered name.
Raises:
ValueError: If the name is empty, or already registered and
``replace`` is ``False``.
"""
name = compressor.descriptor.name
if not name:
raise ValueError("compressor descriptor.name must be non-empty")
if name in self._compressors and not replace:
raise ValueError(f"compressor {name!r} is already registered")
self._compressors[name] = compressor
return name
def get(self, name: str) -> Compressor | None:
"""Return the registered compressor named ``name``, or ``None``."""
return self._compressors.get(name)
def names(self) -> list[str]:
"""Return all registered compressor names, sorted."""
return sorted(self._compressors)
def descriptors(self) -> list[CompressorDescriptor]:
"""Return the descriptors of all registered compressors, sorted by name."""
return [self._compressors[n].descriptor for n in sorted(self._compressors)]
def discover(self, *, replace: bool = False) -> list[str]:
"""Load and register compressors from the ``headroom.compressor`` group.
View on GitHub (pinned to 322425c43b)
Solutions
- If re-registration is intentional, call register(compressor, replace=True).
- Otherwise rename the new compressor's descriptor.name to something unique.
- Guard module-level registration with an idempotency check: if reg.get(name) is None: reg.register(...).
Example fix
# before
reg.register(my_compressor) # second call -> ValueError
# after
if reg.get(my_compressor.descriptor.name) is None:
reg.register(my_compressor)
# or explicit: reg.register(my_compressor, replace=True) Defensive patterns
Strategy: try-catch
Validate before calling
if reg.get(compressor.descriptor.name) is None:
reg.register(compressor)
else:
reg.register(compressor, replace=True) # if re-registration is intended Try / catch
try:
reg.register(compressor)
except ValueError as e:
if "already registered" in str(e):
reg.register(compressor, replace=True)
else:
raise Prevention
- Make module-level registration idempotent (check reg.get first).
- Use replace=True explicitly when overriding a built-in compressor.
- Namespace plugin compressor names (e.g. 'myorg-foo') to avoid collisions.
When it happens
Trigger: Calling register(compressor) twice with the same descriptor.name, or registering a new compressor whose name collides with a built-in; e.g. plugin init running twice, or two modules registering the same name.
Common situations: A plugin and a built-in sharing a name; hot-reload re-executing registration code; a copy-pasted descriptor in tests; double import of a registration module under different names.
Related errors
- Unknown agent: {name!r}. Available: {available}
- unknown tool {tool!r}; known: {sorted(tools)}
- archive did not contain expected member {member!r}
- unknown tool {tool!r}
- No optimizer registered for '{key}'. Available: {available}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/20c3a5ac412af7a9.
Report an issue: GitHub.