headroomlabs-ai/headroom · error · ValueError

dedup_similarity_threshold must be 0.0-1.0, got {self.dedup_

Error message

dedup_similarity_threshold must be 0.0-1.0, got {self.dedup_similarity_threshold}

What it means

ValueError raised in MemoryBridgeConfig.__post_init__ when dedup_similarity_threshold is outside [0.0, 1.0]. This threshold drives near-duplicate detection during markdown imports (default 0.92 cosine similarity); it is a similarity fraction, so the guard ensures a valid range at construction time.

Source

Thrown at headroom/memory/bridge_config.py:66

    default_importance: float = 0.6
    heading_importance_map: dict[int, float] = field(
        default_factory=lambda: {1: 0.9, 2: 0.8, 3: 0.7, 4: 0.6, 5: 0.5, 6: 0.4}
    )
    sync_state_path: Path = field(default_factory=_paths.bridge_state_path)
    auto_import_on_startup: bool = False
    export_path: Path | None = None
    export_format: MarkdownFormat = MarkdownFormat.GENERIC
    extract_entities: bool = True
    chunk_by_section: bool = True
    dedup_similarity_threshold: float = 0.92
    source_tag: str = "memory_bridge"

    def __post_init__(self) -> None:
        """Validate configuration."""
        if not 0.0 <= self.default_importance <= 1.0:
            raise ValueError(f"default_importance must be 0.0-1.0, got {self.default_importance}")
        if not 0.0 <= self.dedup_similarity_threshold <= 1.0:
            raise ValueError(
                f"dedup_similarity_threshold must be 0.0-1.0, got {self.dedup_similarity_threshold}"
            )
        self.md_paths = [Path(p) if isinstance(p, str) else p for p in self.md_paths]
        if isinstance(self.sync_state_path, str):
            self.sync_state_path = Path(self.sync_state_path)
        if self.export_path and isinstance(self.export_path, str):
            self.export_path = Path(self.export_path)

View on GitHub (pinned to 322425c43b)

Solutions

  1. Express it as a fraction: dedup_similarity_threshold=0.95
  2. If migrating from a percent-based config, divide by 100
  3. Remember it is a SIMILARITY threshold (higher = stricter dedup), not a distance threshold

Example fix

# before
cfg = MemoryBridgeConfig(dedup_similarity_threshold=95)  # ValueError

# after
cfg = MemoryBridgeConfig(dedup_similarity_threshold=0.95)
Defensive patterns

Strategy: validation

Validate before calling

def clamp_fraction(name: str, value: float) -> float:
    if not 0.0 <= value <= 1.0:
        raise ValueError(f'{name} must be in [0,1], got {value}')
    return value

cfg = MemoryBridgeConfig(
    dedup_similarity_threshold=clamp_fraction('dedup_similarity_threshold', raw_threshold),
)

Type guard

def is_valid_threshold(v) -> bool:
    return isinstance(v, (int, float)) and not isinstance(v, bool) and 0.0 <= v <= 1.0

Try / catch

try:
    cfg = MemoryBridgeConfig(dedup_similarity_threshold=raw)
except ValueError:
    cfg = MemoryBridgeConfig()  # default 0.92

Prevention

When it happens

Trigger: MemoryBridgeConfig(dedup_similarity_threshold=92) (percentage confusion) or any negative / >1 value; fires instantly in __post_init__ when the dataclass is created.

Common situations: Config authored as a percent (95 instead of 0.95); values copied from a system using distance (0.1) where similarity (0.9) was expected — note the semantic flip too.

Related errors


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