{"record":{"id":"49cd8421a457a917","repo":"headroomlabs-ai/headroom","slug":"unknown-headroom-harness-config-field-name","errorCode":null,"errorMessage":"unknown Headroom harness config field: {name}","messagePattern":"unknown Headroom harness config field: (.+?)","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"warning","filePath":"headroom/testing/harness.py","lineNumber":575,"sourceCode":"\n    @default_mode.setter\n    def default_mode(self, value: str | HeadroomMode) -> None:\n        self.headroom.default_mode = _coerce_headroom_mode(value)\n\n    def __setattr__(self, name: str, value: Any) -> None:\n        if name in {\"headroom\", \"proxy\"}:\n            raise AttributeError(f\"{name} is read-only; mutate its fields instead\")\n        descriptor = getattr(type(self), name, None)\n        if isinstance(descriptor, property) and descriptor.fset is not None:\n            descriptor.fset(self, value)\n            return\n        if hasattr(self.proxy, name):\n            setattr(self.proxy, name, value)\n            return\n        if hasattr(self.headroom, name):\n            setattr(self.headroom, name, value)\n            return\n        raise AttributeError(f\"unknown Headroom harness config field: {name}\")\n\n\nclass Headroom:\n    \"\"\"Fluent scenario builder.\n\n    Example:\n        ``Headroom.with_bedrock(region=\"us-east-1\").on_apple_silicon().configure(...)``\n    \"\"\"\n\n    HARNESS_VERSION = \"1\"\n\n    def __init__(\n        self,\n        *,\n        name: str = \"headroom-scenario\",\n        provider: ProviderTarget = ProviderTarget.ANTHROPIC,\n        platform: PlatformTarget = PlatformTarget.LOCAL,\n        headroom_config: HeadroomConfig | None = None,","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/testing/harness.py#L557-L593","documentation":"AttributeError raised by HeadroomConfig's __setattr__ (headroom/testing/harness.py:575) when an attribute is assigned that is not recognized anywhere: not a property setter on the config class, not an attribute of the nested proxy config, and not an attribute of the nested headroom config. The setter deliberately forwards unknown-but-valid names to the nested configs, so reaching this error means the name is a typo or a field that does not exist in either sub-config (e.g. a field removed in a newer headroom version).","triggerScenarios":"harness.config.proxy_mod = 'cache' (typo); harness.config.some_new_field = 1 after reading docs for a version newer/older than the installed one; assigning a field that only exists on HeadroomConfig's sibling types.","commonSituations":"Version drift between docs and installed package; autocomplete suggesting stale field names; test code written against a different harness major version.","solutions":["Check the spelling against ProxyConfig/HeadroomConfig attributes (dir(harness.config.proxy)).","Prefer the type-checked builders configure_proxy(mode=...) / configure_headroom(...) which give a clearer per-field error (379).","Upgrade/align headroom to the version whose fields you are coding against."],"exampleFix":"# before\nharness.config.proxy_mod = 'cache'  # AttributeError: unknown field\n\n# after\nharness.configure_proxy(mode='cache')","handlingStrategy":"validation","validationCode":"def can_set(harness, name: str) -> bool:\n    cfg = harness.config\n    return (\n        getattr(type(cfg), name, None) is not None\n        or hasattr(cfg.proxy, name)\n        or hasattr(cfg.headroom, name)\n    )","typeGuard":"def is_known_harness_field(harness, name: str) -> bool:\n    cfg = harness.config\n    d = getattr(type(cfg), name, None)\n    return d is not None or hasattr(cfg.proxy, name) or hasattr(cfg.headroom, name)","tryCatchPattern":"try:\n    harness.config.optmize = True\nexcept AttributeError as e:\n    raise RuntimeError(f'check field name: {e}') from e","preventionTips":["Use the configure_* builders instead of direct attribute assignment.","Run a smoke test that sets every field you rely on, so renames surface immediately."],"tags":["testing","harness","api-misuse","typo"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}