Textualize/textual · error · UnexpectedEnd

Unexpected end of file; did you forget a '}' ? / Unexpected

Error message

Unexpected end of file; did you forget a '}' ? / Unexpected end of text

What it means

UnexpectedEnd is a TokenError raised by the tokenizer when input ends while still expecting tokens — with the hint about a missing '}' when the last expectation was a declaration expecting a semicolon, or 'Unexpected end of text' otherwise.

Source

Thrown at src/textual/css/tokenizer.py:254

        Returns:
            A new Token.
        """

        line_no = self.line_no
        col_no = self.col_no
        if line_no >= len(self.lines):
            if expect._expect_eof:
                return Token(
                    "eof",
                    "",
                    self.read_from,
                    self.code,
                    (line_no, col_no),
                    None,
                )
            else:
                raise UnexpectedEnd(
                    self.read_from,
                    self.code,
                    (line_no + 1, col_no + 1),
                    (
                        "Unexpected end of file; did you forget a '}' ?"
                        if expect._expect_semicolon
                        else "Unexpected end of text"
                    ),
                )
        line = self.lines[line_no]
        preceding_text: str = ""
        if expect._extract_text:
            match = expect.search(line, col_no)
            if match is None:
                preceding_text = line[self.col_no :]
                self.line_no += 1
                self.col_no = 0
            else:

View on GitHub (pinned to 06dbeef4bb)

Solutions

  1. Add the missing '}' to close every rule block
  2. Terminate every declaration with ';'
  3. Check the reported line/column — it points at/after the last valid token

Example fix

/* before */
#box { color: red;
/* after */
#box { color: red; }
Defensive patterns

Strategy: validation

Validate before calling

def braces_balanced(css: str) -> bool:
    depth = 0
    for ch in css:
        if ch == '{': depth += 1
        elif ch == '}': depth -= 1
        if depth < 0: return False
    return depth == 0

Try / catch

from textual.css.tokenizer import UnexpectedEnd
try:
    stylesheet.parse()
except UnexpectedEnd as e:
    report(f"unbalanced CSS near line {e.location[0]}: {e}")

Prevention

When it happens

Trigger: Tokenizing CSS that ends mid-declaration or with unclosed braces, e.g. '#box { width: 10' or '$Button { color: red' with no closing brace before EOF.

Common situations: Truncated CSS files, copy-paste losing the final brace, or programmatically concatenated CSS strings missing terminators.

Related errors


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