headroomlabs-ai/headroom · error · ValueError
Unknown scorer tier: {tier}. Valid tiers: {valid_tiers}
Error message
Unknown scorer tier: {tier}. Valid tiers: {valid_tiers} What it means
Raised by create_scorer() when the tier argument does not match 'bm25', 'embedding', or 'hybrid' (tiers are lowercased before comparison, so case is not the issue). It is a plain argument-validation error listing the valid tiers; typos and unsupported aliases are the usual cause.
Source
Thrown at headroom/relevance/__init__.py:124
tier = tier.lower()
if tier == "bm25":
return BM25Scorer(**kwargs)
elif tier == "embedding":
if not EmbeddingScorer.is_available():
raise RuntimeError(
"EmbeddingScorer requires sentence-transformers. "
"Install with: pip install headroom[relevance]"
)
return EmbeddingScorer(**kwargs)
elif tier == "hybrid":
return HybridScorer(**kwargs)
else:
valid_tiers = ["bm25", "embedding", "hybrid"]
raise ValueError(f"Unknown scorer tier: {tier}. Valid tiers: {valid_tiers}")
View on GitHub (pinned to 322425c43b)
Solutions
- Use one of the documented tiers: 'bm25', 'embedding', or 'hybrid'.
- Whitelist the tier in your config schema before passing it through.
- Default missing config values to 'bm25' (the dependency-free tier).
Example fix
# before
scorer = create_scorer(config.get('tier', ''))
# after
scorer = create_scorer(config.get('tier') or 'bm25') Defensive patterns
Strategy: validation
Validate before calling
VALID_TIERS = {'bm25', 'embedding', 'hybrid'}
tier = (config.get('tier') or 'bm25').lower()
if tier not in VALID_TIERS:
raise ConfigError(f'tier must be one of {sorted(VALID_TIERS)}, got {config.get("tier")!r}')
scorer = create_scorer(tier) Type guard
def is_scorer_tier(tier: str) -> bool:
return isinstance(tier, str) and tier.lower() in {'bm25', 'embedding', 'hybrid'} Try / catch
try:
scorer = create_scorer(tier)
except ValueError as e:
raise ConfigError(str(e)) from e # surface to config validation layer Prevention
- Constrain the tier field in your config schema to the three allowed values.
- Default unset tier config to 'bm25'.
- Add an allowlist test that fails when library tiers change across upgrades.
When it happens
Trigger: Calling create_scorer('vector'), create_scorer('embeddings'), create_scorer('BM25 ') with trailing content, or passing a None/default from an unset config field.
Common situations: Config drift between your app's tier names and the library's; renamed tiers across versions; empty string from a missing config key.
Related errors
- invalid pipeline config TOML: {0}
- recommendations file not found: {0}
- bedrock_eventstream_parse_failed
- items_json must be JSON: {e}
- doc_json must be JSON: {e}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/b29f6d78ad3fc23f.
Report an issue: GitHub.