kovidgoyal/kitty · error
Could not parse delegate command: %#v with error: %w
Error message
Could not parse delegate command: %#v with error: %w
What it means
run_ssh shlex-splits the host's delegate command and the split itself failed, so the configured delegate (a command that replaces ssh, like mossh or et) could not be turned into an argv. The raw string and the parse error are included.
Source
Thrown at kittens/ssh/main.go:668
}
host_opts, bad_lines, err := load_config(hostname_for_match, uname, overrides)
if err != nil {
return 1, err
}
// check the secrets syntax here as askpass has no good way to report errors to
// the user
if err = resolve_secrets(host_opts, true); err != nil {
return 1, err
}
if len(bad_lines) > 0 {
for _, x := range bad_lines {
fmt.Fprintf(os.Stderr, "Ignoring bad config line: %s:%d with error: %s", filepath.Base(x.Src_file), x.Line_number, x.Err)
}
}
if host_opts.Delegate != "" {
delegate_cmd, err := shlex.Split(host_opts.Delegate)
if err != nil {
return 1, fmt.Errorf("Could not parse delegate command: %#v with error: %w", host_opts.Delegate, err)
}
return 1, unix.Exec(utils.FindExe(delegate_cmd[0]), utils.Concat(delegate_cmd, ssh_args, server_args), os.Environ())
}
master_is_alive, master_checked := false, false
var control_master_args []string
if host_opts.Share_connections {
kpid, err := strconv.Atoi(os.Getenv("KITTY_PID"))
if err != nil {
return 1, fmt.Errorf("Invalid KITTY_PID env var not an integer: %#v", os.Getenv("KITTY_PID"))
}
control_master_args, err = connection_sharing_args(kpid)
if err != nil {
return 1, err
}
cmd = slices.Insert(cmd, insertion_point, control_master_args...)
}
use_kitty_askpass := host_opts.Askpass == Askpass_native || (host_opts.Askpass == Askpass_unless_set && os.Getenv("SSH_ASKPASS") == "")
need_to_request_data := trueView on GitHub (pinned to 6d5d0c4406)
Solutions
- Check the Delegate value in your config for unmatched quotes/backslashes and fix them
- Test the lexing: kitty +kitten ssh with the value echoed, or run shlex-equivalent (python3 -c 'import shlex; print(shlex.split(...))')
- Quote the whole delegate command once and avoid nested quotes
- After fixing, rerun the kitten to confirm exec proceeds
Example fix
# before .delegate "my-wrapper --flag 'value # after .delegate "my-wrapper --flag value"
Defensive patterns
Strategy: validation
Validate before calling
if _, err := shlex.Split(delegateCmd); err != nil {
// reject/repair the config line before running
} Try / catch
if _, err := run_ssh(...); err != nil && strings.Contains(err.Error(), "Could not parse delegate command") {
// surface config file and line to the user
} Prevention
- Lint delegate lines with shlex.Split at config load time
- Keep delegate commands simple; avoid nested quotes
- Test delegate values in a scratch config before committing
When it happens
Trigger: A ssh kitten Delegate option whose value contains unbalanced quotes, stray backslashes, or other shell-lexing errors; shlex.Split returns an error for malformed quoting.
Common situations: Hand-edited kitty.conf/ssh config with missing closing quote ('delegate "mossh'); Windows-style paths with backslashes; copy-pasting a shell line containing characters the simple lexer rejects; empty first token after a weird split.
Related errors
- No theme named %#v found
- The menu entry name in {val} must end with a double quote
- Invalid listen-on value: {spec} must be of the form protocol
- Unknown protocol in listen-on value: {spec}
- Unknown action in option `notify_on_cmd_finish`: {action}
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/96f7417881263e25.
Report an issue: GitHub.