{"record":{"id":"14783dbb4cc36acb","repo":"kovidgoyal/kitty","slug":"path-is-not-a-supported-shell","errorCode":null,"errorMessage":"{path} is not a supported shell","messagePattern":"(.+?) is not a supported shell","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/shell_integration.py","lineNumber":208,"sourceCode":"def get_supported_shell_name(path: str) -> str | None:\n    name = os.path.basename(path)\n    if name.lower().endswith('.exe'):\n        name = name.rpartition('.')[0]\n    if name.startswith('-'):\n        name = name[1:]\n    return name if name in ENV_MODIFIERS else None\n\n\ndef shell_integration_allows_rc_modification(opts: Options) -> bool:\n    return not (opts.shell_integration & {'disabled', 'no-rc'})\n\n\ndef serialize_env(path: str, env: dict[str, str]) -> str:\n    if not env:\n        return ''\n    name = get_supported_shell_name(path)\n    if not name:\n        raise ValueError(f'{path} is not a supported shell')\n    return ENV_SERIALIZERS[name](env)\n\n\n@run_once\ndef unsafe_pat() -> re.Pattern[str]:\n    return re.compile(r'[^\\w@%+=:,./-]', re.ASCII)\n\n\ndef join(path: str, cmd: Iterable[str]) -> str:\n    name = get_supported_shell_name(path)\n    _find_unsafe = unsafe_pat().search\n    if not name:\n        raise ValueError(f'{path} is not a supported shell')\n    q = QUOTERES.get(name, as_str_literal)\n\n    def quote(x: str) -> str:\n        return x if _find_unsafe(x) is None else q(x)\n","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/shell_integration.py#L190-L226","documentation":"serialize_env encodes a dict of environment variables into shell syntax for a supported shell (zsh/bash/fish). It resolves the shell by path via get_supported_shell_name; if the path doesn't match a known supported shell, it raises this ValueError because no serializer exists for that shell.","triggerScenarios":"Calling serialize_env('/usr/bin/fish'...) is fine, but calling it with '/usr/bin/tcsh', '/bin/dash', a custom shell path, or a path whose basename isn't in the supported set raises this. Typically reached via clone_and_launch / shell integration env propagation.","commonSituations":"User's SHELL or kitty's shell config points to an unsupported shell (nushell, elvish, xonsh, tcsh); distro-specific shell paths; a wrapper script as the shell.","solutions":["Set the shell to a supported one: zsh, bash, or fish (e.g. shell /bin/bash in kitty.conf)","If using a wrapper, point kitty directly at the real supported shell binary","Catch the ValueError and fall back to not injecting the env via shell-integration serialization"],"exampleFix":"# before\nkitty.conf: shell /usr/bin/tcsh\n# after\nkitty.conf: shell /bin/bash","handlingStrategy":"fallback","validationCode":"from kitty.shell_integration import get_supported_shell_name\n\ndef can_serialize(shell_path: str) -> bool:\n    return bool(get_supported_shell_name(shell_path))","typeGuard":null,"tryCatchPattern":"try:\n    blob = serialize_env(shell_path, env)\nexcept ValueError:\n    blob = ''  # skip env injection for unsupported shells\n    log_warning(f'env not serialized for {shell_path}')","preventionTips":["Restrict env injection to zsh/bash/fish","Resolve the real shell binary path before calling","Catch ValueError and degrade instead of crashing"],"tags":["kitty","shell-integration","unsupported-shell","environment"],"backgroundTag":"unsupported-shell","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}