Textualize/textual · error · CSSPathError
Expected a str, Path or list[str | Path] for the CSS_PATH.
Error message
Expected a str, Path or list[str | Path] for the CSS_PATH.
What it means
CSSPathError raised by textual's CSS path normalization when the CSS_PATH class variable is not a str, Path/PurePath, or a list of those. The App constructor validates CSS_PATH before mounting.
Source
Thrown at src/textual/_path.py:42
Args:
css_path: Value to be normalized.
Raises:
CSSPathError: If the argument has the wrong format.
Returns:
A list of paths.
"""
paths: list[PurePath] = []
if isinstance(css_path, str):
paths = [Path(css_path)]
elif isinstance(css_path, PurePath):
paths = [css_path]
elif isinstance(css_path, list):
paths = [Path(path) for path in css_path]
else:
raise CSSPathError("Expected a str, Path or list[str | Path] for the CSS_PATH.")
return paths
def _make_path_object_relative(path: str | PurePath, obj: object) -> Path:
"""Convert the supplied path to a Path object that is relative to a given Python object.
If the supplied path is absolute, it will simply be converted to a Path object.
Used, for example, to return the path of a CSS file relative to a Textual App instance.
Args:
path: A path.
obj: A Python object to resolve the path relative to.
Returns:
A resolved Path object, relative to obj
"""
path = Path(path)
View on GitHub (pinned to 06dbeef4bb)
Solutions
- Use a plain string CSS_PATH = "app.css" or a Path object
- If multiple stylesheets, use an explicit list: CSS_PATH = ["a.css", "b.css"]
- Convert other iterables to list before assigning: CSS_PATH = list(paths)
Example fix
# before
class MyApp(App):
CSS_PATH = ("app.css", "extra.css")
# after
class MyApp(App):
CSS_PATH = ["app.css", "extra.css"] Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
css = ('app.css', 'extra.css')
assert isinstance(css, (str, Path, list)), 'CSS_PATH must be str/Path/list' Type guard
def valid_css_path(p) -> bool:
import pathlib
return isinstance(p, (str, pathlib.Path, pathlib.PurePath)) or (
isinstance(p, list) and all(isinstance(x, (str, pathlib.Path)) for x in p)
) Try / catch
try:
app.run()
except CSSPathError:
app.CSS_PATH = [str(p) for p in app.CSS_PATH] # then retry Prevention
- Always write CSS_PATH as a string or explicit list
- Run the app once in CI to catch class-definition-time issues
When it happens
Trigger: Setting CSS_PATH = ('app.css', 'extra.css') (a tuple), a set, None, or a dict on an App subclass and then running it.
Common situations: Developers switch from list to tuple literal, refactor CSS_PATH dynamically, or copy-paste configs from other frameworks expecting different types.
Related errors
- {self.name} must be one of {friendly_list(self._valid_values
- {self.name} must be a str
- invalid percentage value '{token}'
- Invalid color value {color}
- unknown word {word!r} in style flags
AI-assisted analysis of Textualize/textual@06dbeef4bb (2026-08-27).
Data as JSON: /api/errors/763cf531ea3efbf0.
Report an issue: GitHub.