{"record":{"id":"0d7cff1e2b8b1ffc","repo":"Textualize/textual","slug":"valid-rule-orientations-are-friendly-list-valid","errorCode":null,"errorMessage":"Valid rule orientations are {friendly_list(_VALID_RULE_ORIENTATIONS)}","messagePattern":"Valid rule orientations are (.+?)","errorType":"exception","errorClass":"InvalidRuleOrientation","httpStatus":null,"severity":"error","filePath":"src/textual/widgets/_rule.py","lineNumber":176,"sourceCode":"        self.orientation = orientation\n        self.line_style = line_style\n        self.expand = True\n\n    def render(self) -> RenderResult:\n        rule_character: str\n        style = self.rich_style\n        if self.orientation == \"vertical\":\n            rule_character = _VERTICAL_LINE_CHARS[self.line_style]\n            return VerticalRuleRenderable(\n                rule_character, style, self.content_size.height\n            )\n        elif self.orientation == \"horizontal\":\n            rule_character = _HORIZONTAL_LINE_CHARS[self.line_style]\n            return HorizontalRuleRenderable(\n                rule_character, style, self.content_size.width\n            )\n        else:\n            raise InvalidRuleOrientation(\n                f\"Valid rule orientations are {friendly_list(_VALID_RULE_ORIENTATIONS)}\"\n            )\n\n    def watch_orientation(\n        self, old_orientation: RuleOrientation, orientation: RuleOrientation\n    ) -> None:\n        self.remove_class(f\"-{old_orientation}\")\n        self.add_class(f\"-{orientation}\")\n\n    def validate_orientation(self, orientation: RuleOrientation) -> RuleOrientation:\n        if orientation not in _VALID_RULE_ORIENTATIONS:\n            raise InvalidRuleOrientation(\n                f\"Valid rule orientations are {friendly_list(_VALID_RULE_ORIENTATIONS)}\"\n            )\n        return orientation\n\n    def validate_line_style(self, style: LineStyle) -> LineStyle:\n        if style not in _VALID_LINE_STYLES:","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/widgets/_rule.py#L158-L194","documentation":"Raised by Rule.render when the orientation reactive is neither 'horizontal' nor 'vertical' — render handles horizontal and vertical branches and this else covers any other value. In practice it is hard to reach because validate_orientation also guards assignment, but a corrupted/orientation set via internals would hit it at render time.","triggerScenarios":"Rule(orientation='diagonal') or rule.orientation = 'up' — an invalid orientation string reaching render; typically blocked earlier by validate_orientation raising at assignment time.","commonSituations":"Passing a custom string that type-checks as RuleOrientation in loose typing, or bypassing validation via internal state.","solutions":["Use only 'horizontal' or 'vertical' (the RuleOrientation literal values).","Assign through the public constructor/reactive so validate_orientation catches mistakes early.","Check _VALID_RULE_ORIENTATIONS in textual/widgets/_rule.py."],"exampleFix":"# before\nRule(orientation='diag')\n# after\nRule(orientation='horizontal')","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_orientation(v: str) -> bool: return v in ('horizontal', 'vertical')","tryCatchPattern":null,"preventionTips":["Only use 'horizontal' or 'vertical'","Let validate_orientation catch bad values at assignment, never bypass reactives"],"tags":["rule","orientation","validation","textual"],"backgroundTag":"invalid-enum-value","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}