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 markup
What it means
UnexpectedEnd raised by Tokenizer.skip_to when scanning forward (e.g. to the end of a block or declaration list) hits the end of input. Message hints at a missing '}' when a semicolon was expected, else 'Unexpected end of markup'.
Source
Thrown at src/textual/css/tokenizer.py:365
def skip_to(self, expect: Expect) -> Token:
"""Skip tokens.
Args:
expect: Expect object describing the expected token.
Raises:
UnexpectedEndOfText: If end of file is reached.
Returns:
A new token.
"""
line_no = self.line_no
col_no = self.col_no
while True:
if line_no >= len(self.lines):
raise UnexpectedEnd(
self.read_from,
self.code,
(line_no, col_no),
(
"Unexpected end of file; did you forget a '}' ?"
if expect._expect_semicolon
else "Unexpected end of markup"
),
)
line = self.lines[line_no]
match = expect.search(line, col_no)
if match is None:
line_no += 1
col_no = 0
else:
self.line_no = line_no
self.col_no = match.span(0)[0]View on GitHub (pinned to 06dbeef4bb)
Solutions
- Close every '{' with a matching '}'
- Ensure declaration lists are terminated
- Validate CSS strings before passing them to Stylesheet by counting braces
Example fix
/* before */
Screen { layout: vertical;
/* after */
Screen { layout: vertical; } Defensive patterns
Strategy: validation
Validate before calling
def css_terminators_ok(css: str) -> bool:
css = css.strip()
return css.endswith('}') and '{' not in css.split('}')[-1] and braces_balanced(css) Try / catch
from textual.css.tokenizer import UnexpectedEnd
try:
stylesheet.parse()
except UnexpectedEnd as e:
report(f"missing '}}' near {e.location}: {e}") Prevention
- Close every block with '}'
- Terminate declaration lists
- Brace-count generated CSS
When it happens
Trigger: skip_to(',') or skip_to(';') on input where the terminator never appears — typically an unclosed rule block or a declaration list that runs to EOF without its closing brace/semicolon.
Common situations: Same class of issues as [106]: truncated or hand-written CSS missing the closing '}' — but surfacing through the skip-to recovery path rather than get_token's main loop.
Related errors
- Unexpected end of file; did you forget a '}' ? / Unexpected
- {expect.description} (found {error_line.split(';')[0]!r}). ;
- Expected a str, Path or list[str | Path] for the CSS_PATH.
- {self.name} must be one of {friendly_list(self._valid_values
- {self.name} must be a str
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/d356ef34db8bd77a.
Report an issue: GitHub.