{"record":{"id":"24c6335d87efce95","repo":"Textualize/textual","slug":"self-name-must-be-a-str-e-g-10-or-a-float","errorCode":null,"errorMessage":"{self.name} must be a str (e.g. '10%') or a float (e.g. 0.1)","messagePattern":"(.+?) must be a str \\(e\\.g\\. '10%'\\) or a float \\(e\\.g\\. 0\\.1\\)","errorType":"validation","errorClass":"StyleValueError","httpStatus":null,"severity":"error","filePath":"src/textual/css/_style_properties.py","lineNumber":1194,"sourceCode":"\n        Args:\n            obj: The Styles object.\n            value: The value to set as a float between 0 and 1, or\n                as a percentage string such as '10%'.\n        \"\"\"\n        _rich_traceback_omit = True\n        name = self.name\n        if value is None:\n            if obj.clear_rule(name):\n                obj.refresh(children=self.children)\n            return\n\n        if isinstance(value, (int, float)):\n            float_value = float(value)\n        elif isinstance(value, str) and value.endswith(\"%\"):\n            float_value = float(Scalar.parse(value).value) / 100\n        else:\n            raise StyleValueError(\n                f\"{self.name} must be a str (e.g. '10%') or a float (e.g. 0.1)\",\n                help_text=fractional_property_help_text(name, context=\"inline\"),\n            )\n        if obj.set_rule(name, clamp(float_value, 0, 1)):\n            obj.refresh(children=self.children)\n\n\nclass AlignProperty:\n    \"\"\"Combines the horizontal and vertical alignment properties into a single property.\"\"\"\n\n    def __set_name__(self, owner: StylesBase, name: str) -> None:\n        self.horizontal = f\"{name}_horizontal\"\n        self.vertical = f\"{name}_vertical\"\n\n    def __get__(\n        self, obj: StylesBase, type: type[StylesBase]\n    ) -> tuple[AlignHorizontal, AlignVertical]:\n        horizontal = getattr(obj, self.horizontal)","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/css/_style_properties.py#L1176-L1212","documentation":"FractionalProperty (used by rules like `opacity`, and other 0–1 fractional styles) accepts a number (int/float) or a percentage string such as '10%'. Any other value — a bare non-percent string like '0.5', None, or an object — raises StyleValueError explaining the two accepted forms.","triggerScenarios":"`styles.opacity = \"0.5\"` (string without %), `styles.opacity = \"50 percent\"`, `styles.opacity = None`, or `opacity: half;` in TCSS.","commonSituations":"Assuming any numeric string parses; reading values from config where numbers arrive as strings without conversion.","solutions":["Pass a float/int (`0.5`, `1`) or a percent string (`'50%'`)","Convert numeric strings from config with float() before assignment"],"exampleFix":"# before\nstyles.opacity = \"0.5\"\n# after\nstyles.opacity = 0.5  # or \"50%\"","handlingStrategy":"validation","validationCode":"if isinstance(v, (int, float)) or (isinstance(v, str) and v.endswith(\"%\")):\n    styles.opacity = v\nelse:\n    styles.opacity = float(v)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Convert numeric config strings with float() before assigning fractional styles"],"tags":["textual","css","fractional","validation"],"backgroundTag":"invalid-css-value","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}