Textualize/textual · error · ScalarParseError

{token!r} is not a valid scalar

Error message

{token!r} is not a valid scalar

What it means

Raised by Scalar.parse when the token doesn't match the scalar pattern (e.g. '10', '50%', 'auto'). Textual CSS requires dimensions and offsets to be a number with an optional unit; anything else fails regex matching and raises ScalarParseError.

Source

Thrown at src/textual/css/scalar.py:261

    @lru_cache(maxsize=1024)
    def parse(cls, token: str, percent_unit: Unit = Unit.WIDTH) -> Scalar:
        """Parse a string into a Scalar

        Args:
            token: A string containing a scalar, e.g. "3.14fr"

        Raises:
            ScalarParseError: If the value is not a valid scalar

        Returns:
            New scalar
        """
        if token.lower() == "auto":
            scalar = cls(1.0, Unit.AUTO, Unit.AUTO)
        else:
            match = _MATCH_SCALAR(token)
            if match is None:
                raise ScalarParseError(f"{token!r} is not a valid scalar")
            value, unit_name = match.groups()
            scalar = cls(float(value), SYMBOL_UNIT[unit_name or ""], percent_unit)
        return scalar

    @lru_cache(maxsize=4096)
    def resolve(
        self, size: Size, viewport: Size, fraction_unit: Fraction | None = None
    ) -> Fraction:
        """Resolve scalar with units into a dimensions.

        Args:
            size: Size of the container.
            viewport: Size of the viewport (typically terminal size)

        Raises:
            ScalarResolveError: If the unit is unknown.

        Returns:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Correct the token to a valid scalar: number + unit (e.g. '10', '50%', '3fr', '4w') or 'auto'
  2. Validate user-provided dimension strings with a regex before passing them to Scalar.parse or styling APIs
  3. If building values programmatically, format them explicitly, e.g. f'{value}%', instead of concatenating raw input

Example fix

// before
scalar = Scalar.parse(user_input)  # user_input = 'half'
// after
scalar = Scalar.parse('50%')
Defensive patterns

Strategy: validation

Validate before calling

import re
_SCALAR_RE = re.compile(r'^auto$|^[+-]?(\d+(\.\d+)?|\.\d+)(%|fr|w|h|vw|vh| cells)?$|^[+-]?\d+(w|h)$', re.I)
def is_valid_scalar(token: str) -> bool:
    return _SCALAR_RE.match(token.strip()) is not None

Type guard

def is_scalar_token(t: object) -> bool:
    return isinstance(t, str) and is_valid_scalar(t)

Try / catch

from textual.css.scalar import ScalarParseError
try:
    s = Scalar.parse(token)
except ScalarParseError as e:
    log.warning(f"ignoring invalid scalar {token!r}: {e}")
    s = Scalar.from_number(1)

Prevention

When it happens

Trigger: Calling Scalar.parse(token) with strings like 'ten', '10 px' (space), '1.2.3', or '#fff'. Also triggered by CSS/TCSS values in stylesheets where a scalar is expected but the value is malformed.

Common situations: Typos in TCSS files (missing unit symbol, stray characters), dynamically building style strings from user input, or passing a raw number instead of a string.

Related errors


AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27). Data as JSON: /api/errors/626825db3f1b2a5c. Report an issue: GitHub.