headroomlabs-ai/headroom · error · ValueError
compressor descriptor.name must be non-empty
Error message
compressor descriptor.name must be non-empty
What it means
Raised by CompressorRegistry.register when compressor.descriptor.name is an empty string. The registry keys compressors by name for later get(name) lookups and router wiring, so an empty name cannot be addressed and is rejected before insertion.
Source
Thrown at headroom/transforms/compressor_registry.py:184
def register(self, compressor: Compressor, *, replace: bool = False) -> str:
"""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]:View on GitHub (pinned to 322425c43b)
Solutions
- Set a unique, non-empty descriptor.name before registering.
- If descriptors come from config, fail fast at parse time on a missing/empty name with the config path in the message.
- Add a test that every shipped compressor registers successfully.
Example fix
# before reg.register(MyCompressor(CompressorDescriptor(name=""))) # after reg.register(MyCompressor(CompressorDescriptor(name="smart-crusher")))
Defensive patterns
Strategy: validation
Validate before calling
name = compressor.descriptor.name
if not name:
raise ConfigError("compressor descriptor.name missing")
reg.register(compressor) Type guard
def has_valid_descriptor_name(c: Compressor) -> bool:
return bool(getattr(c.descriptor, "name", "")) Try / catch
try:
reg.register(compressor)
except ValueError as e:
if "must be non-empty" in str(e):
raise ConfigError(f"compressor from {source!r} has no name") from e
raise Prevention
- Require descriptor.name in config schemas (minLength: 1).
- Fail at startup on unnamed compressors, not lazily at first use.
- Test that every built-in compressor registers.
When it happens
Trigger: Registering a compressor whose CompressorDescriptor was built with name="" (or the field was omitted and defaulted empty in a dict-based construction).
Common situations: Building a descriptor from config where the name key is missing; a dataclass default of "" leaking through; programmatic registration in a loop where the name variable is unset for one entry.
Related errors
- bedrock_eventstream_parse_failed
- Unknown provider: {self.llm_config.provider}
- HEADROOM_LEARN_CLI={cli_override!r} is not a supported CLI.
- Unknown agent: {name!r}. Available: {available}
- max_size must be at least 1, got {max_size}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/f2d1203195770a7f.
Report an issue: GitHub.