Textualize/textual · error · StyleTypeError
{self.name} must be a str
Error message
{self.name} must be a str What it means
The NameProperty descriptor (used for the `layer`-like name rules such as `link`-style names) requires either None (to clear the rule) or a Python str. Passing any other type (int, list, Color, etc.) raises StyleTypeError. This guards the internal rule storage which only accepts string identifiers.
Source
Thrown at src/textual/css/_style_properties.py:932
return obj.get_rule(self.name, "") # type: ignore[return-value]
def __set__(self, obj: StylesBase, name: str | None):
"""Set the name property.
Args:
obj: The ``Styles`` object.
name: The name to set the property to.
Raises:
StyleTypeError: If the value is not a ``str``.
"""
_rich_traceback_omit = True
if name is None:
if obj.clear_rule(self.name):
obj.refresh(layout=True)
else:
if not isinstance(name, str):
raise StyleTypeError(f"{self.name} must be a str")
if obj.set_rule(self.name, name):
obj.refresh(layout=True)
class NameListProperty:
def __set_name__(self, owner: StylesBase, name: str) -> None:
self.name = name
def __get__(
self, obj: StylesBase, objtype: type[StylesBase] | None = None
) -> tuple[str, ...]:
return obj.get_rule(self.name, ()) # type: ignore[return-value]
def __set__(self, obj: StylesBase, names: str | tuple[str] | None = None):
_rich_traceback_omit = True
if names is None:
if obj.clear_rule(self.name):
obj.refresh(layout=True)View on GitHub (pinned to 06dbeef4bb)
Solutions
- Coerce the value to str before assignment, or pass None to clear the rule
- Validate external config values with a type check before applying them to styles
Example fix
# before styles.link_id = 42 # after styles.link_id = str(42) # or None to clear
Defensive patterns
Strategy: type-guard
Validate before calling
if name is None or isinstance(name, str):
styles.link_id = name Type guard
def is_style_name(v) -> bool:
return v is None or isinstance(v, str) Prevention
- Normalize external style values to str or None before applying
When it happens
Trigger: `styles.link_id = 42`, `styles.<name-rule> = ['a','b']`, or passing a non-str variable from user input into a name-style assignment instead of a string or None.
Common situations: Programmatically building styles from unvalidated data (JSON config, DB rows) where the name field is a number; forgetting that None clears the rule while other falsy values like 0 do not.
Related errors
- {self.name} must be one of {friendly_list(self._valid_values
- Invalid color value {color}
- Expected a str, Path or list[str | Path] for the CSS_PATH.
- invalid percentage value '{token}'
- unknown word {word!r} in style flags
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/b8695c71616e21b4.
Report an issue: GitHub.