antonmedv/fx · error
Invalid Unicode escape sequence '\u%s'
Error message
Invalid Unicode escape sequence '\u%s'
What it means
In strict mode, scanString read 4 hex digits after \u but strconv.ParseInt failed — this occurs when the code point is a surrogate half used incorrectly... practically it fires when the hex string is out of the int32 range ParseInt(s,16,32) accepts (only possible with weird state) or, per the code path, when the parsed hex value cannot fit; the message shows the hex digits.
Source
Thrown at internal/jsonx/json.go:227
p.next()
escaped := false
for {
if escaped {
escaped = false
if p.strict {
switch p.char {
case 'u':
var s string
for i := 0; i < 4; i++ {
p.next()
if !utils.IsHexDigit(p.char) {
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()
}
View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Replace the raw \u escape with the literal UTF-8 character in the input
- Re-encode the document with encoding/json so all escapes are well-formed
- Decode surrogate pairs correctly (two \uXXXX halves) or use a single code point escape
- If the input is machine-generated, fix the generator to emit only valid \uXXXX (0000–FFFF) escapes
Example fix
// before
"\u{1F600}" // invalid JS-style escape
// after
"\uD83D\uDE00" // surrogate pair, or literal "😀" Defensive patterns
Strategy: validation
Validate before calling
// Validate hex payload of \u escapes fits int32
for _, m := range unicodeEscapes.FindAllStringSubmatch(string(b), -1) {
if _, err := strconv.ParseInt(m[1], 16, 32); err != nil {
return fmt.Errorf("bad unicode escape %s", m[0])
}
} Try / catch
defer func() {
if r := recover(); r != nil {
if msg, ok := r.(string); ok && strings.Contains(msg, "Invalid Unicode escape") {
err = fmt.Errorf("unparseable unicode escape: %s", msg)
}
}
}() Prevention
- Emit only \uXXXX (0000–FFFF) escapes from generators
- Use literal UTF-8 characters for code points above U+FFFF
- Normalize surrogate pairs before embedding escapes
- Round-trip test payloads through encoding/json
When it happens
Trigger: Parse (strict) encountering '\u' + 4 hex chars that ParseInt(s, 16, 32) rejects; with 4 valid hex digits max value 0xFFFF this is rare, but the branch guards it and reports the full hex sequence.
Common situations: Generated or obfuscated JSON containing unusual \u sequences; tooling that emits escapes like \uFFFF+ beyond intent; also hit when investigating surrogate pairs '\uD83D\uDE00' if surrounding validation is strict.
Related errors
- Invalid Unicode escape sequence '\u%s%c'
- Invalid escape sequence '\%c'
- Invalid character code point %d in string
- Unexpected end of input in string
- Invalid character %q in number
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/a90a4b75e868ea9f.
Report an issue: GitHub.