github/copilot-sdk · error · IllegalArgumentException
Invalid Unicode escape at position <pos-1>
Error message
Invalid Unicode escape at position <pos-1>
What it means
parseUnicodeEscape expects four ASCII hex digits after \u. One of the four characters read was not a valid hex digit (0-9, a-f, A-F), so the escape is malformed. The error reports the position of the offending character (pos-1).
Solutions
- Correct the escape to contain exactly four hex digits, e.g. '\u00e9'
- If the intent was a literal '\uXXXX' placeholder, escape the backslash: '\\uXXXX'
- Inspect the character at the reported position to identify the typo
- Prefer a JSON serializer (it emits valid escapes or raw UTF-8) over manual escaping
Example fix
// before
String json = "{\"ch\":\"\\u00zz\"}"; // z not hex
// after
String json = "{\"ch\":\"\\u00e9\"}"; Defensive patterns
Strategy: try-catch
Validate before calling
java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\\\\\\\u(?![0-9a-fA-F]{4})").matcher(json);
if (m.find()) {
throw new IllegalArgumentException("Non-hex digit in \\u escape at index " + m.start());
} Try / catch
try {
String result = CopilotToolProcessor.jsonToMapOfSource(json);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Invalid Unicode escape")) {
// correct the hex digits at the reported position
}
} Prevention
- Verify \u escapes contain only [0-9a-fA-F]
- Search generated payloads for literal 'XXXX' placeholders that were never substituted
- Use decimal code points only as digits after \u (\u00e9, not \u233)
- Round-trip generated JSON through a reference parser before use
When it happens
Trigger: Escapes like '\u00zz', '\u 0e9', or '\u+123' inside a JSON string — anything where one of the four chars after \u is outside [0-9a-fA-F].
Common situations: Hand-written Unicode escapes with typos; placeholders like '\uXXXX' left unsubstituted by a template engine; mistaken use of '\u' with decimal or signed values.
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
- Incomplete Unicode escape at position <pos-2>
- Unterminated string escape at position
- Invalid escape sequence \
- Unexpected trailing content at position
- Unescaped control character at position <pos-1>
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/5be52ae6bd0b7a3b.
Report an issue: GitHub.
Appendix: source
Thrown at java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java:1068
case 'f' -> '\f';
case 'n' -> '\n';
case 'r' -> '\r';
case 't' -> '\t';
case 'u' -> parseUnicodeEscape();
default -> throw new IllegalArgumentException(
"Invalid escape sequence \\" + escaped + " at position " + (pos - 2));
};
}
private char parseUnicodeEscape() {
if (pos + 4 > input.length()) {
throw new IllegalArgumentException("Incomplete Unicode escape at position " + (pos - 2));
}
int value = 0;
for (int i = 0; i < 4; i++) {
char hex = input.charAt(pos++);
if (!isAsciiHexDigit(hex)) {
throw new IllegalArgumentException("Invalid Unicode escape at position " + (pos - 1));
}
int digit = Character.digit(hex, 16);
value = (value << 4) | digit;
}
return (char) value;
}
private boolean isAsciiHexDigit(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
private String parseBoolean() {
if (input.startsWith("true", pos)) {
pos += 4;
return "true";
}
if (input.startsWith("false", pos)) {
pos += 5;View on GitHub (pinned to cd8cf15dc3)