karatelabs/karate · error
Invalid hex digit ' ' in \u escape
Error message
Invalid hex digit '${h}' in \u escape What it means
Thrown by JsonParser.parseHex4 when one of the four characters following a '\u' escape is not a hexadecimal digit (0-9, a-f, A-F). JSON's '\u' escape requires exactly four hex digits, so characters like 'g', 'z', or '/' are rejected.
Solutions
- Correct the escape to exactly four hex digits, e.g. '\u00gg' → '\u0047'.
- If the backslash should be literal (like a Windows path), double it: '\\Users' instead of '\Users'.
- Pad short escapes to four digits: '\u9' → '\u0009'.
- Generate unicode escapes programmatically (String.format('\\u%04x', codePoint)) to avoid typos.
Example fix
// before
'{"ch": "\u00gg"}'
// after
'{"ch": "\u0047"}' Defensive patterns
Strategy: validation
Validate before calling
// Verify every \u escape is followed by exactly 4 hex digits
private static final java.util.regex.Pattern U_ESCAPE =
java.util.regex.Pattern.compile("\\\\u([0-9a-fA-F]{4})");
static boolean allUnicodeEscapesValid(String s) {
java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\\\u.{0,4}").matcher(s);
while (m.find()) {
if (!U_ESCAPE.matcher(m.group()).matches()) return false;
}
return true;
} Try / catch
try {
return Json.parse(raw);
} catch (JsonSyntaxException e) {
if (e.getMessage().contains("hex digit")) {
throw new IllegalArgumentException("Malformed \\uXXXX escape; expected 4 hex digits", e);
}
throw e;
} Prevention
- Use only 0-9/a-f/A-F in \u escapes and always four of them.
- Double backslashes for literal Windows paths (\\Users) so they aren't read as escapes.
- Zero-pad short code points: tab is \u0009, not \u9 or \utab.
- Test fixtures with a JSON linter that validates escape sequences.
When it happens
Trigger: Parsing strings with malformed unicode escapes like '\u00gg', '\u12x4', or '\u abcd' — any non-hex character in the four-digit position after '\u'.
Common situations: Hand-typed unicode escapes with typos, escaping confusion where a '\u' was meant literally (e.g. Windows '\Users' paths in JSON should be '\\Users'), generated escapes truncated to fewer than 4 digits.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Invalid \u escape in JSON string
- [callSingle] disk cache read failed
- Cannot convert null or undefined to object
- Converting circular structure to JSON
- Do not know how to serialize a BigInt
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/6efbb9fe88ab4258.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsonParser.java:248
}
sb.append(c);
pos++;
}
throw syntaxError("Unterminated JSON string");
}
private char parseHex4() {
if (pos + 4 > len) {
throw syntaxError("Invalid \\u escape in JSON string");
}
int v = 0;
for (int i = 0; i < 4; i++) {
char h = s.charAt(pos + i);
int d;
if (h >= '0' && h <= '9') d = h - '0';
else if (h >= 'a' && h <= 'f') d = 10 + (h - 'a');
else if (h >= 'A' && h <= 'F') d = 10 + (h - 'A');
else throw syntaxError("Invalid hex digit '" + h + "' in \\u escape");
v = (v << 4) | d;
}
pos += 4;
return (char) v;
}
private Object parseNumber() {
int start = pos;
boolean isFloat = false;
if (s.charAt(pos) == '-') {
pos++;
if (pos >= len) {
throw syntaxError("Invalid number: bare '-'");
}
}
// integer part
char c = s.charAt(pos);
if (c == '0') {View on GitHub (pinned to a22eb90246)