Textualize/rich · error · ValueError
'characters' argument must have a cell width of at least 1
Error message
'characters' argument must have a cell width of at least 1
What it means
Rule renders a horizontal line built by repeating its characters= string. rich validates that the string has a display (cell) width of at least 1, measured with cell_len — which understands East Asian wide characters and zero-width joins. A string of only zero-width/combining characters (cell width 0) cannot draw a line, so Rule raises ValueError at construction.
Source
Thrown at rich/rule.py:33
Args:
title (Union[str, Text], optional): Text to render in the rule. Defaults to "".
characters (str, optional): Character(s) used to draw the line. Defaults to "─".
style (StyleType, optional): Style of Rule. Defaults to "rule.line".
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:View on GitHub (pinned to 9d8f9a372c)
Solutions
- Default to '─' (U+2500) or pass a real visible character: Rule('Title', characters='=') .
- Validate config-supplied separators before use: if not chars or cell_len(chars) < 1: use fallback.
- For an invisible divider, use a space-padded character like ' ' plus a style, or render a blank Text instead of a zero-width Rule.
Example fix
# before
print(Rule('Header', characters='')) # ValueError: cell width of at least 1
# after
chars = cfg.get('rule_chars') or '─'
print(Rule('Header', characters=chars)) Defensive patterns
Strategy: validation
Validate before calling
from rich.cells import cell_len
chars = cfg.get('rule_chars', '')
if cell_len(chars) < 1:
chars = '─'
rule = Rule('Title', characters=chars) Type guard
def is_valid_rule_characters(chars: str) -> bool:
return isinstance(chars, str) and cell_len(chars) >= 1 Prevention
- Validate user/config-supplied separator strings with rich.cells.cell_len before constructing Rule.
- Treat empty separator config as 'use default' rather than passing it through.
When it happens
Trigger: Rule(characters=''), Rule(characters='\u200b') (zero-width space), Rule(characters='\u0301') (combining mark), or any sequence whose combined cell width is 0. Note: a string like '──' is fine; the check is width, not count.
Common situations: User-configurable separator characters (CLI themes, config files) where an empty string slips through; loading separator settings from YAML/JSON where the value is blank; passing a stripped/normalized string that ended up empty; characters read from a source that lost a zero-width glyph.
Related errors
- invalid value for align, expected "left", "center", "right"
- 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/306c6eefcf7e812f.
Report an issue: GitHub.