kovidgoyal/kitty · warning · ValueError
Invalid characters in visual_window_select_characters: {x} O
Error message
Invalid characters in visual_window_select_characters: {x} Only numbers (0-9) and alphabets (a-z,A-Z) are allowed. Ignoring. What it means
visual_window_select_characters validator raises this when, after uppercasing, the set of characters contains anything outside digits, ASCII uppercase, and the punctuation "-=[]\\;',./`". kitty uses these characters to label windows during visual window selection mode.
Source
Thrown at kitty/options/utils.py:818
return positive_float(parts[0]), -1.0
return positive_float(parts[0]), positive_float(parts[1])
def resize_debounce_time(x: str) -> tuple[float, float]:
parts = x.split(maxsplit=1)
if len(parts) == 1:
return positive_float(parts[0]), 0.5
return positive_float(parts[0]), positive_float(parts[1])
def visual_window_select_characters(x: str) -> str:
import string
valid_characters = string.digits + string.ascii_uppercase + "-=[]\\;',./`"
ans = x.upper()
ans_chars = set(ans)
if not ans_chars.issubset(set(valid_characters)):
raise ValueError(f'Invalid characters in visual_window_select_characters: {x} Only numbers (0-9) and alphabets (a-z,A-Z) are allowed. Ignoring.')
if len(ans_chars) < len(x):
raise ValueError(f'Invalid characters in visual_window_select_characters: {x} Contains identical numbers or alphabets, case insensitive. Ignoring.')
return ans
def tab_separator(x: str) -> str:
for q in '\'"':
if x.startswith(q) and x.endswith(q):
x = x[1:-1]
if not x:
return ''
break
if not x.strip():
x = ('\xa0' * len(x)) if x else default_tab_separator
return x
def tab_bar_edge(x: str) -> int:View on GitHub (pinned to 6d5d0c4406)
Solutions
- Restrict to 0-9, a-z/A-Z and the allowed punctuation set
- Keep the default or extend only with allowed punctuation characters
Example fix
# before visual_window_select_characters 0123456789abcdef!@ # after visual_window_select_characters 0123456789abcdef
Defensive patterns
Strategy: validation
Validate before calling
import string
ALLOWED = set(string.digits + string.ascii_uppercase + "-=[]\\;',./`")
def valid_vwsc(x: str) -> bool:
return set(x.upper()).issubset(ALLOWED) Prevention
- Only alphanumerics plus the documented punctuation
- Reject spaces/unicode before writing config
When it happens
Trigger: Setting visual_window_select_characters to include spaces, unicode letters, or other punctuation like '!' or '@'.
Common situations: Wanting more selectable windows than the default 0-9A-Z allows and adding invalid symbols.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- The window layout {p} is unknown
- Invalid characters in visual_window_select_characters: {x} C
- This should be run as kitten broadcast
- No option named: {k}
- No custom kitten named {kitten} found
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/3c5a00260e2deb3a.
Report an issue: GitHub.