antonmedv/fx · error

Invalid Unicode escape sequence '\u%s%c'

Error message

Invalid Unicode escape sequence '\u%s%c'

What it means

Inside a string literal in strict mode, scanString found a \u escape whose 4 hex digits are incomplete — the character right after the digits read so far is not a hex digit. The message includes the hex digits collected and the offending character.

Source

Thrown at internal/jsonx/json.go:221

		LineNumber: p.lineNumberPlusPlus(),
	}
}

func (p *JsonParser) scanString() string {
	start := p.end - 1
	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")

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Fix the string so every \u is followed by exactly 4 hex digits (e.g. '\u0041' instead of '\uA')
  2. Use the actual character directly in the source (UTF-8 'A') instead of a \u escape
  3. Escape properly with a JSON encoder (encoding/json Marshal) instead of hand-building escapes
  4. If non-strict semantics suffice, disable strict mode; scanString only validates escapes when p.strict is true

Example fix

// before
"caf\u00e"
// after
"caf\u00e9"  // or "café"
Defensive patterns

Strategy: validation

Validate before calling

re := regexp.MustCompile(`\\\\u[0-9a-fA-F]{4}`)
// ensure every backslash-u in string literals has 4 hex digits
if strings.Contains(string(b), "\\u") && !re.Match(b) { return errors.New("malformed \\u escape") }

Try / catch

defer func() {
	if r := recover(); r != nil {
		if msg, ok := r.(string); ok && strings.Contains(msg, "Invalid Unicode escape") {
			err = errors.New("input contains malformed \\uXXXX escape")
		}
	}
}()

Prevention

When it happens

Trigger: Parsing a string containing '\u12z4', '\u00', or '\u' followed by end-of-input/non-hex character while the parser runs in strict mode; called via Parse -> parseString -> scanString.

Common situations: Hand-rolled string escaping in generated code, template engines that only partially expand \uXXXX escapes, copy-paste from sources that mangled unicode escapes, truncated files cutting an escape mid-sequence.

Related errors


AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02). Data as JSON: /api/errors/32aa615bdc000afc. Report an issue: GitHub.