{"record":{"id":"9f0c555ce032be6a","repo":"Textualize/textual","slug":"unable-to-read-css-file-filename-r","errorCode":null,"errorMessage":"unable to read CSS file {filename!r}","messagePattern":"unable to read CSS file (.+?)","errorType":"exception","errorClass":"StylesheetError","httpStatus":null,"severity":"error","filePath":"src/textual/css/stylesheet.py","lineNumber":304,"sourceCode":"        return rules\n\n    def read(self, filename: str | PurePath) -> None:\n        \"\"\"Read Textual CSS file.\n\n        Args:\n            filename: Filename of CSS.\n\n        Raises:\n            StylesheetError: If the CSS could not be read.\n            StylesheetParseError: If the CSS is invalid.\n        \"\"\"\n        filename = os.path.expanduser(filename)\n        try:\n            with open(filename, \"rt\", encoding=\"utf-8\") as css_file:\n                css = css_file.read()\n            path = os.path.abspath(filename)\n        except Exception:\n            raise StylesheetError(f\"unable to read CSS file {filename!r}\") from None\n        self.source[(str(path), \"\")] = CssSource(css, False, 0)\n        self._require_parse = True\n\n    def read_all(self, paths: Sequence[PurePath]) -> None:\n        \"\"\"Read multiple CSS files, in order.\n\n        Args:\n            paths: The paths of the CSS files to read, in order.\n\n        Raises:\n            StylesheetError: If the CSS could not be read.\n            StylesheetParseError: If the CSS is invalid.\n        \"\"\"\n        for path in paths:\n            self.read(path)\n\n    def has_source(self, path: str, class_var: str = \"\") -> bool:\n        \"\"\"Check if the stylesheet has this CSS source already.","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/css/stylesheet.py#L286-L322","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"# before\nCSS_PATH = \"style.tcss\"  # resolved against CWD\n# after\nCSS_PATH = Path(__file__) / \"style.tcss\"","handlingStrategy":"validation","validationCode":"from pathlib import Path\np = Path(__file__).parent / \"style.tcss\"\nif not p.is_file():\n    raise FileNotFoundError(p)","typeGuard":null,"tryCatchPattern":"from textual.css.stylesheet import StylesheetError\ntry:\n    ss.read(css_path)\nexcept StylesheetError:\n    ss.read(DEFAULT_CSS_PATH)  # fallback theme","preventionTips":["Build CSS paths from __file__, not CWD","Include .tcss files in package data","Fail fast in CI if CSS files are missing"],"tags":["textual","css","filenotfound","stylesheet","io"],"backgroundTag":"css-file-load-failed","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}