Textualize/textual · error · TypeError
value must be a str
Error message
value must be a str
What it means
A TypeError raised in Digits.__init__ when the value argument is not a str. Digits renders text made of Unicode block characters and has no numeric coercion, so ints/floats must be converted by the caller (e.g. via f-strings or format()).
Source
Thrown at src/textual/widgets/_digits.py:48
value: str = "",
*,
name: str | None = None,
id: str | None = None,
classes: str | None = None,
disabled: bool = False,
) -> None:
"""Initialize a Digits widget.
Args:
value: Value to display in widget.
name: The name of the widget.
id: The ID of the widget in the DOM.
classes: The CSS classes of the widget.
disabled: Whether the widget is disabled or not.
"""
if not isinstance(value, str):
raise TypeError("value must be a str")
super().__init__(name=name, id=id, classes=classes, disabled=disabled)
self._value = value
@property
def value(self) -> str:
"""The current value displayed in the Digits."""
return self._value
def get_selection(self, selection: Selection) -> str | None:
return self._value
def update(self, value: str) -> None:
"""Update the Digits with a new value.
Args:
value: New value to display.
Raises:View on GitHub (pinned to 06dbeef4bb)
Solutions
- Convert to string first: Digits(str(value)) or Digits(f'{value:.2f}').
- For times, format explicitly: Digits(time.strftime('%H:%M:%S')).
- Add a type assertion at the call site if value comes from untyped data.
Example fix
# before digits = Digits(12345) # after digits = Digits(str(12345))
Defensive patterns
Strategy: type-guard
Validate before calling
value = str(value) if not isinstance(value, str) else value Digits(value)
Type guard
def is_display_str(value: object) -> bool:
return isinstance(value, str) Prevention
- Always format numerics with str() or f-strings before passing to Digits
- Centralize formatting for clock/counter values
When it happens
Trigger: Constructing Digits(123) or Digits(3.14) with a number; passing bytes; passing a computed numeric value directly from a counter or clock.
Common situations: Building clock/counter widgets and passing time.time() or datetime values; assuming Digits works like Input with type coercion.
Related errors
- Widget positional arguments must be Widget subclasses; not {
- Tried to insert a widget with ID {widget_id!r}, but a widget
- {self.name} must be a str
- Invalid color value {color}
- No {name!r} key in COMPONENT_CLASSES
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/4624fc5667f009e0.
Report an issue: GitHub.