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

  1. Correct the escape to contain exactly four hex digits, e.g. '\u00e9'
  2. If the intent was a literal '\uXXXX' placeholder, escape the backslash: '\\uXXXX'
  3. Inspect the character at the reported position to identify the typo
  4. 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

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


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)