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

  1. Use one of the documented tiers: 'bm25', 'embedding', or 'hybrid'.
  2. Whitelist the tier in your config schema before passing it through.
  3. 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

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


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/b29f6d78ad3fc23f. Report an issue: GitHub.