{"record":{"id":"55d5be54bebbb2bd","repo":"headroomlabs-ai/headroom","slug":"invalid-rollout-worker-unsafe-override","errorCode":null,"errorMessage":"invalid rollout worker unsafe override","messagePattern":"invalid rollout worker unsafe override","errorType":"exception","errorClass":"RolloutConfigurationError","httpStatus":null,"severity":"error","filePath":"headroom/rollout.py","lineNumber":298,"sourceCode":"            \"legacy_requested\": sorted(self.config.legacy_requested),\n            \"legacy_disabled\": sorted(self.config.legacy_disabled),\n        }\n\n    @classmethod\n    def from_internal_dict(cls, value: Mapping[str, object]) -> RolloutSnapshot:\n        \"\"\"Validate and restore a snapshot serialized for worker handoff.\"\"\"\n\n        if not isinstance(value, Mapping):\n            raise RolloutConfigurationError(\"invalid rollout worker snapshot\")\n        try:\n            if value.get(\"schema_version\") != ROLLOUT_SCHEMA_VERSION:\n                raise RolloutConfigurationError(\"unsupported rollout worker schema version\")\n            if value.get(\"policy_version\") != ROLLOUT_POLICY_VERSION:\n                raise RolloutConfigurationError(\"rollout worker policy version mismatch\")\n            channel = RolloutChannel.parse(str(value[\"channel\"]), strict=True)\n            unsafe = value[\"unsafe_allow_unstable\"]\n            if not isinstance(unsafe, bool):\n                raise RolloutConfigurationError(\"invalid rollout worker unsafe override\")\n\n            def names(field: str) -> set[str]:\n                raw = value[field]\n                if not isinstance(raw, list) or not all(isinstance(item, str) for item in raw):\n                    raise RolloutConfigurationError(f\"invalid rollout worker field {field!r}\")\n                return set(_validate_names(set(raw), source=field, strict=True))\n\n            snapshot = _resolve_snapshot(\n                channel=channel,\n                explicit_requested=names(\"explicit_requested\"),\n                explicit_disabled=names(\"explicit_disabled\"),\n                legacy_requested=names(\"legacy_requested\"),\n                legacy_disabled=names(\"legacy_disabled\"),\n                unsafe=unsafe,\n            )\n        except (KeyError, TypeError) as exc:\n            raise RolloutConfigurationError(\"invalid rollout worker snapshot\") from exc\n        if value.get(\"registry_digest\") != snapshot.registry_digest:","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/rollout.py#L280-L316","documentation":"Raised by RolloutSnapshot.from_internal_dict() when the 'unsafe_allow_unstable' field is present but not a bool (e.g. the string 'true' or an int 1). Because this flag bypasses stability protections, the restore path requires an actual JSON boolean rather than a truthy value of another type.","triggerScenarios":"from_internal_dict({'unsafe_allow_unstable': 'true', ...}) or 1/0 ints — typical when the dict was built from env vars or form data instead of to_internal_dict().","commonSituations":"Serializing a snapshot with values sourced from environment variables (always strings); a worker framework coercing booleans to ints; hand-written test fixtures.","solutions":["Produce handoff dicts via to_internal_dict() so the field is a real bool.","Convert strings before restore: unsafe in (True, False) or bool parsing in your adapter.","Never inject env-var strings directly into the handoff payload."],"exampleFix":"# before\npayload['unsafe_allow_unstable'] = os.environ.get('UNSAFE', 'false')\n\n# after\npayload['unsafe_allow_unstable'] = os.environ.get('UNSAFE', 'false').lower() == 'true'","handlingStrategy":"type-guard","validationCode":"unsafe = payload.get('unsafe_allow_unstable')\nif not isinstance(unsafe, bool):\n    raise ValueError('unsafe_allow_unstable must be a bool')","typeGuard":"def is_bool_field(value: object) -> bool:\n    return isinstance(value, bool)  # note: True/1 are distinct in isinstance(bool, ...)","tryCatchPattern":"try:\n    snapshot = RolloutSnapshot.from_internal_dict(payload)\nexcept RolloutConfigurationError as e:\n    if 'unsafe override' in str(e):\n        payload['unsafe_allow_unstable'] = bool(payload['unsafe_allow_unstable'])\n        snapshot = RolloutSnapshot.from_internal_dict(payload)\n    else:\n        raise","preventionTips":["Never place env-var strings into handoff payloads; coerce to real booleans first.","Serialize with to_internal_dict() so types are correct by construction.","Validate payload types with a JSON schema (additionalProperties with types) at the producer."],"tags":["serialization","rollout","type-validation","boolean"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}