antonmedv/fx · error
Unexpected end of input in string
Error message
Unexpected end of input in string
What it means
scanString reached end-of-input (p.char == 0 sentinel set on EOF) while still scanning a string literal — the closing double quote was never found. The library panics because a string cannot be terminated.
Source
Thrown at internal/jsonx/json.go:239
panic(fmt.Sprintf("Invalid Unicode escape sequence '\\u%s%c'", s, p.char))
}
s += string(p.char)
}
_, err := strconv.ParseInt(s, 16, 32)
if err != nil {
panic(fmt.Sprintf("Invalid Unicode escape sequence '\\u%s'", s))
}
case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
default:
panic(fmt.Sprintf("Invalid escape sequence '\\%c'", p.char))
}
}
} else if p.char == '\\' {
escaped = true
} else if p.char == '"' {
break
} else if p.char == 0 {
panic("Unexpected end of input in string")
} else if rune(p.char) > unicode.MaxRune {
panic(fmt.Sprintf("Invalid character code point %d in string", p.char))
}
p.next()
}
str := string(p.data[start:p.end])
p.next()
return str
}
func (p *JsonParser) parseMinus() *Node {
start := p.end - 1
p.next()
switch p.char {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
return p.parseNumber(start)View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Check the input source for truncation and re-fetch/re-download the complete document
- Add the missing closing quote at the reported line
- Verify file sizes / Content-Length vs received bytes when reading from network or disk
- Recover in the caller and report a user-friendly 'unterminated string at line N' message
Example fix
// before
{"name": "unclosed
// after
{"name": "unclosed"} Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap sanity check: balanced double quotes outside escapes
func quotesBalanced(b []byte) bool {
inStr, esc := false, false
for _, c := range b {
if esc { esc = false; continue }
switch c {
case '\\':
if inStr { esc = true }
case '"':
inStr = !inStr
}
}
return !inStr
} Try / catch
func parse(b []byte) (n *jsonx.Node, err error) {
defer func() {
if r := recover(); r != nil {
if msg, ok := r.(string); ok && strings.Contains(msg, "Unexpected end of input") {
err = errors.New("truncated input: unterminated string")
}
}
}()
return jsonx.Parse(b, true), nil
} Prevention
- Read the full stream to EOF before parsing; check io.ReadAll errors
- Verify Content-Length / file size on network payloads
- Never split JSON documents at arbitrary byte boundaries
- Log the last 100 bytes of failed payloads to spot truncation
When it happens
Trigger: Parse on input where an opening '"' is never closed, e.g. `{"key": "value}` or a file truncated mid-string; also when the input ends immediately after an opening quote.
Common situations: Truncated network responses or downloads, log lines cut mid-record, editors saving partial files, streaming reads where the producer crashed, accidental deletion of the closing quote during hand edits.
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
- Invalid Unicode escape sequence '\u%s%c'
- Invalid Unicode escape sequence '\u%s'
- Invalid escape sequence '\%c'
- Invalid character code point %d in string
- Invalid character %q in number
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/222ae7768a6b7a0c.
Report an issue: GitHub.