Textualize/rich · error · ValueError
invalid value for align, expected "left", "center", "right"
Error message
invalid value for align, expected "left", "center", "right" (not {align!r}) What it means
Rule.__init__ validates its align keyword against the literal set ('left', 'center', 'right') and raises ValueError with the offending value otherwise. The check happens before any rendering, at construction time, so a bad align fails immediately when Rule(...) is created.
Source
Thrown at rich/rule.py:37
end (str, optional): Character at end of Rule. defaults to "\\\\n"
align (str, optional): How to align the title, one of "left", "center", or "right". Defaults to "center".
"""
def __init__(
self,
title: Union[str, Text] = "",
*,
characters: str = "─",
style: Union[str, Style] = "rule.line",
end: str = "\n",
align: AlignMethod = "center",
) -> None:
if cell_len(characters) < 1:
raise ValueError(
"'characters' argument must have a cell width of at least 1"
)
if align not in ("left", "center", "right"):
raise ValueError(
f'invalid value for align, expected "left", "center", "right" (not {align!r})'
)
self.title = title
self.characters = characters
self.style = style
self.end = end
self.align = align
def __repr__(self) -> str:
return f"Rule({self.title!r}, {self.characters!r})"
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
width = options.max_width
characters = (
"-"View on GitHub (pinned to 9d8f9a372c)
Solutions
- Use exactly 'left', 'center', or 'right' (lowercase, American spelling).
- Normalize external values before constructing: align = str(align).lower() and validate against a whitelist, falling back to 'center'.
- If align comes from config, add a validation/enum in your settings schema.
Example fix
# before
print(Rule('Title', align='centre')) # ValueError: invalid value for align
# after
align = cfg.get('align', 'center').lower()
if align not in ('left', 'center', 'right'):
align = 'center'
print(Rule('Title', align=align)) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = ('left', 'center', 'right')
align = str(align).lower()
if align not in ALLOWED:
align = 'center'
rule = Rule('Title', align=align) Type guard
def is_valid_align(value: str) -> bool:
"""Narrow a string to a rich Rule AlignMethod."""
return isinstance(value, str) and value in ('left', 'center', 'right') Prevention
- Lowercase and whitelist external align values before use.
- Remember only exact lowercase 'left'/'center'/'right' are accepted ('centre' fails).
When it happens
Trigger: Rule('T', align='centre') (British spelling), Rule(align='middle'), Rule(align='Center') (capital C), or an align pulled from user/config data such as Rule(align=cfg['align']).
Common situations: Config files with 'centre'/'middle' spellings; case-sensitive values from user input ('Left'); passing constants from another library (e.g. matplotlib's 'center' vs a custom enum) without mapping.
Related errors
- 'characters' argument must have a cell width of at least 1
- invalid value for align, expected "left", "center", or "righ
- invalid value for vertical, expected "top", "middle", or "bo
- level must be 'head', 'row' or 'foot'
- unable to get the total number of bytes, please specify 'tot
AI-assisted analysis of Textualize/rich@9d8f9a372c (2026-08-15).
Data as JSON: /api/errors/e5712f36e726d9e1.
Report an issue: GitHub.