Textualize/textual · error · StylesheetError
unable to read CSS file
Error message
unable to read CSS file {filename!r} What it means
Stylesheet.read raises StylesheetError when the CSS file cannot be opened or read (missing file, permission error, decode error). The original exception is suppressed with 'from None'.
Solutions
- Check CSS_PATH spelling and make it relative to __file__ using Path(__file__).parent
- Use absolute paths or pathlib to build the CSS path
- Ensure the .tcss/.css file is included in package data when shipping
Example fix
# before CSS_PATH = "style.tcss" # resolved against CWD # after CSS_PATH = Path(__file__) / "style.tcss"
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path(__file__).parent / "style.tcss"
if not p.is_file():
raise FileNotFoundError(p) Try / catch
from textual.css.stylesheet import StylesheetError
try:
ss.read(css_path)
except StylesheetError:
ss.read(DEFAULT_CSS_PATH) # fallback theme Prevention
- Build CSS paths from __file__, not CWD
- Include .tcss files in package data
- Fail fast in CI if CSS files are missing
When it happens
Trigger: Stylesheet.read('theme.tcss') where the path doesn't exist, lacks read permissions, or is not UTF-8. Also triggered by app-level CSS_PATH pointing at a nonexistent file.
Common situations: Wrong CSS_PATH relative to the app file, files not packaged in a distribution/wheel, permission issues, or paths containing '~' expansion problems (expanduser is applied, but relative paths resolve against CWD).
Related errors
- DeclarationError(name, token, message)
- failed to parse css;
- StylesheetErrors(css_rules) (renderable summarizing CSS…
- cannot mix 'none' with other style flags
- DeclarationError(error.name, error.token, error.message)
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/9f0c555ce032be6a.
Report an issue: GitHub.
Appendix: source
Thrown at src/textual/css/stylesheet.py:304
return rules
def read(self, filename: str | PurePath) -> None:
"""Read Textual CSS file.
Args:
filename: Filename of CSS.
Raises:
StylesheetError: If the CSS could not be read.
StylesheetParseError: If the CSS is invalid.
"""
filename = os.path.expanduser(filename)
try:
with open(filename, "rt", encoding="utf-8") as css_file:
css = css_file.read()
path = os.path.abspath(filename)
except Exception:
raise StylesheetError(f"unable to read CSS file {filename!r}") from None
self.source[(str(path), "")] = CssSource(css, False, 0)
self._require_parse = True
def read_all(self, paths: Sequence[PurePath]) -> None:
"""Read multiple CSS files, in order.
Args:
paths: The paths of the CSS files to read, in order.
Raises:
StylesheetError: If the CSS could not be read.
StylesheetParseError: If the CSS is invalid.
"""
for path in paths:
self.read(path)
def has_source(self, path: str, class_var: str = "") -> bool:
"""Check if the stylesheet has this CSS source already.View on GitHub (pinned to 06dbeef4bb)