Textualize/rich · error · TypeError

Only str or Text can be appended to Text

Error message

Only str or Text can be appended to Text

What it means

Text.append(text, style=None) only accepts str or Text instances — anything else raises TypeError('Only str or Text can be appended to Text'). The restriction exists because append must copy spans and sanitize control codes, which is only defined for those two types; there is no implicit str() coercion of numbers, styled tuples, or other renderables.

Source

Thrown at rich/text.py:978

                self.pad_right(excess_space - left, character)
            else:
                self.pad_left(excess_space, character)

    def append(
        self, text: Union["Text", str], style: Optional[Union[str, "Style"]] = None
    ) -> "Text":
        """Add text with an optional style.

        Args:
            text (Union[Text, str]): A str or Text to append.
            style (str, optional): A style name. Defaults to None.

        Returns:
            Text: Returns self for chaining.
        """

        if not isinstance(text, (str, Text)):
            raise TypeError("Only str or Text can be appended to Text")

        if len(text):
            if isinstance(text, str):
                sanitized_text = strip_control_codes(text)
                self._text.append(sanitized_text)
                offset = len(self)
                text_length = len(sanitized_text)
                if style:
                    self._spans.append(Span(offset, offset + text_length, style))
                self._length += text_length
            elif isinstance(text, Text):
                _Span = Span
                if style is not None:
                    raise ValueError(
                        "style must not be set when appending Text instance"
                    )
                text_length = self._length
                if text.style:

View on GitHub (pinned to 9d8f9a372c)

Solutions

  1. Convert non-text values first: text.append(str(value)).
  2. For other rich renderables, don't append — use Columns/Group or a render group instead of Text concatenation.
  3. Decode bytes before appending: text.append(data.decode('utf-8')).

Example fix

# before
text.append(count)  # TypeError if count is int

# after
text.append(str(count))
Defensive patterns

Strategy: type-guard

Validate before calling

value = value if isinstance(value, (str, Text)) else str(value)
text.append(value, style=style)

Type guard

from rich.text import Text
from typing import Union

def appendable(value: object) -> Union[str, Text]:
    """Coerce anything to a Text-appendable value."""
    return value if isinstance(value, (str, Text)) else str(value)

Try / catch

try:
    t.append(v)
except TypeError:
    t.append(str(v))

Prevention

When it happens

Trigger: text.append(42), text.append(3.14), text.append(None), text.append(some_renderable), or text.append(b'bytes'). The isinstance check runs before any length test, so even 'empty-looking' wrong types raise.

Common situations: Building log/table cells by concatenating computed numeric values without str(); mixing rich Text with plain Python types in f-string-free code paths; appending bytes from a network layer; passing a Panel/Table/other renderable where its text was intended.

Related errors


AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15). Data as JSON: /api/errors/c2156287ee371c8e. Report an issue: GitHub.