kovidgoyal/kitty · warning
Extra backslash at end of input
Error message
Extra backslash at end of input
What it means
The shlex lexer encountered a backslash as the last character of input while in word-start/normal state, so there is no character following the escape. It records a Trailer of "\\" and this error on the LexResult instead of silently dropping the escape.
Source
Thrown at tools/utils/shlex/shlex.go:102
const escape_char = '\\'
for self.src_pos < self.src_sz {
ch := self.src[self.src_pos]
self.src_pos++
switch self.state {
case lex_normal:
switch ch {
case ' ', '\n', '\r', '\t':
case string_with_escapes_delim:
self.state = string_with_escapes
self.start_word()
case string_without_escapes_delim:
self.state = string_without_escapes
self.start_word()
case escape_char:
self.start_word()
if !self.write_escaped_ch() {
ans.Trailer = "\\"
ans.Err = fmt.Errorf("Extra backslash at end of input")
ans.Pos = self.word_start
return
}
self.state = word
default:
self.state = word
self.start_word()
self.write_ch(ch)
}
case word:
switch ch {
case ' ', '\n', '\r', '\t':
self.state = lex_normal
if self.buf.Len() > 0 {
return self.get_word()
}
case string_with_escapes_delim:
self.state = string_with_escapesView on GitHub (pinned to 6d5d0c4406)
Solutions
- Strip a single trailing backslash (line continuation) before splitting: strings.TrimSuffix(s, "\\").
- Escape it as a doubled backslash if a literal backslash is intended.
- In completion mode, check ans.Trailer == "\\" and treat it as in-progress input rather than an error.
- Reject the input early with a regexp like /\\$/.
Example fix
// before parts, err := shlex.Split(userInput) // after userInput = strings.TrimSuffix(userInput, "\\") parts, err := shlex.Split(userInput)
Defensive patterns
Strategy: validation
Validate before calling
if strings.HasSuffix(s, "\\") && !strings.HasSuffix(s, "\\\\") {
s = strings.TrimSuffix(s, "\\")
} Type guard
func hasBalancedEscapes(s string) bool {
return !strings.HasSuffix(s, "\\")
} Try / catch
words, ans := shlex.Split(s)
if ans.Err != nil && strings.Contains(ans.Err.Error(), "Extra backslash") {
s = strings.TrimSuffix(s, "\\")
words, ans = shlex.Split(s)
} Prevention
- Trim trailing line-continuation backslashes before splitting.
- Double backslashes meant literally.
- For completion, branch on ans.Trailer == "\\" as 'still typing'.
When it happens
Trigger: Calling Split/SplitForCompletion on input ending in an unquoted trailing backslash, e.g. `Split("echo foo\\")`. The escape_char case in state 'starting a word' finds no next rune via write_escaped_ch().
Common situations: User-supplied shell command lines pasted with a trailing backslash (line-continuation artifact), or paths on Windows ending in '\' passed to a Unix-style splitter; completion code splitting partial input where the user just typed a backslash.
Related errors
- Unterminated string at end of input
- Too much piped data
- Canceled by user
- Execute command
- No lexer available for this format
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/c673793272b91087.
Report an issue: GitHub.