github/copilot-sdk · error · IllegalArgumentException

Expected ' ' at position but got '<char|EOF>

Error message

Expected '<c>' at position <pos> but got '<char|EOF>'

What it means

The expect(c) helper in CopilotToolProcessor's JSON parser asserts that the current character equals the expected structural character (e.g. ':', ',', '}', ']') and advances; otherwise it throws IllegalArgumentException reporting the expected character, position, and what was actually found (or EOF). This is the generic structural-mismatch error of the hand-rolled parser.

Solutions

  1. Use the message's position/actual-character info to fix the delimiter at that spot.
  2. Validate the JSON with a standard parser before passing it to the tool.
  3. Catch IllegalArgumentException around the parse and fall back to a lenient JSON repair library.

Example fix

// before
{"name": "x" "age": 1}
// after
{"name": "x", "age": 1}
Defensive patterns

Strategy: try-catch

Validate before calling

static void assertWellFormed(String json) {
    try { new com.fasterxml.jackson.databind.ObjectMapper().readTree(json); }
    catch (java.io.IOException e) { throw new IllegalArgumentException("not valid JSON", e); }
}

Type guard

static boolean looksLikeJsonObject(String s) {
    String t = s == null ? "" : s.trim();
    return t.startsWith("{") && t.endsWith("}");
}

Try / catch

try {
    processor.parse(args);
} catch (IllegalArgumentException e) {
    // message contains: expected char, position, actual char — surface both to the caller
    return Result.syntaxError(parsePosFrom(e.getMessage()), e.getMessage());
}

Prevention

When it happens

Trigger: Malformed JSON such as missing colons ({"a" 1}), missing commas between members, wrong closing bracket ([1}), or trailing text where the delimiter was expected.

Common situations: LLM tool-call arguments with dropped punctuation, hand-edited JSON, single quotes used instead of double quotes, unquoted keys or trailing commas in unexpected spots.

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/83b95b5b694926c0. Report an issue: GitHub.

Appendix: source

Thrown at java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java:1177

            while (pos < input.length() && isJsonWhitespace(input.charAt(pos))) {
                pos++;
            }
        }

        private boolean isJsonWhitespace(char c) {
            return c == ' ' || c == '\t' || c == '\r' || c == '\n';
        }

        private char peek() {
            if (pos >= input.length()) {
                throw new IllegalArgumentException("Unexpected end of JSON");
            }
            return input.charAt(pos);
        }

        private void expect(char c) {
            if (pos >= input.length() || input.charAt(pos) != c) {
                throw new IllegalArgumentException("Expected '" + c + "' at position " + pos + " but got '"
                        + (pos < input.length() ? input.charAt(pos) : "EOF") + "'");
            }
            pos++;
        }

        private boolean tryConsume(char c) {
            if (pos < input.length() && input.charAt(pos) == c) {
                pos++;
                return true;
            }
            return false;
        }
    }

    private static String escapeJava(String s) {
        if (s == null) {
            return "";
        }

View on GitHub (pinned to cd8cf15dc3)