evanw/esbuild · error · LexerPanic

Unicode escape sequence is out of range

Error message

Unicode escape sequence is out of range

What it means

While decoding a variable-length Unicode code-point escape '\u{...}', esbuild computes the hex value and rejects it if it exceeds utf8.MaxRune (U+10FFFF). Code points above U+10FFFF are not valid Unicode scalars and cannot be encoded in UTF-8/16, so the escape is illegal.

Source

Thrown at internal/js_lexer/js_lexer.go:2365

							if isFirst {
								return nil, false, start + i - width3
							}
							break variableLength
						default:
							return nil, false, start + i - width3
						}

						if value > utf8.MaxRune {
							isOutOfRange = true
						}

						isFirst = false
					}

					if isOutOfRange && reportErrors {
						lexer.addRangeError(logger.Range{Loc: logger.Loc{Start: int32(start + hexStart)}, Len: int32(i - hexStart)},
							"Unicode escape sequence is out of range")
						panic(LexerPanic{})
					}
				} else {
					// Fixed-length
					for j := 0; j < 4; j++ {
						switch c3 {
						case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
							value = value*16 | (c3 - '0')
						case 'a', 'b', 'c', 'd', 'e', 'f':
							value = value*16 | (c3 + 10 - 'a')
						case 'A', 'B', 'C', 'D', 'E', 'F':
							value = value*16 | (c3 + 10 - 'A')
						default:
							return nil, false, start + i - width3
						}

						if j < 3 {
							c3, width3 = utf8.DecodeRuneInString(text[i:])
							i += width3

View on GitHub (pinned to f6058f8364)

Solutions

  1. Use a valid code point (<= U+10FFFF).
  2. If the value is generated, clamp/validate it to the 0..0x10FFFF range before emitting.
  3. Substitute the literal character or a valid \u escape.

Example fix

// before
const x = "\u{110000}"
// after
const x = "\u{1F600}"
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/evanw/esbuild/pkg/api"
res := api.Transform(src, api.TransformOptions{Loader: api.LoaderJS})
for _, m := range res.Errors {
  if strings.Contains(m.Text, "Unicode escape sequence is out of range") {
    // surface m.Location; reject this input
  }
}

Type guard

// Validate every \u{...} in source: value must be <= utf8.MaxRune.
var reEsc = regexp.MustCompile(`\\u\{([0-9A-Fa-f]+)\}`)
func unicodeEscapesValid(src string) bool {
  for _, m := range reEsc.FindAllStringSubmatch(src, -1) {
    v, err := strconv.ParseUint(m[1], 16, 32)
    if err != nil || v > utf8.MaxRune { return false }
  }
  return true
}

Prevention

When it happens

Trigger: A '\u{...}' escape whose hex digits evaluate to > 0x10FFFF, e.g. "\u{110000}", appearing in a string, identifier, or template literal.

Common situations: Code generators that splice arbitrary integers into '\u{}'; copy-paste of surrogate-pair math; misunderstanding that the max code point is U+10FFFF.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/e0be95996badd378. Report an issue: GitHub.