github/copilot-sdk · error · IllegalArgumentException

Expected null at position

Error message

Expected null at position <pos>

What it means

The converter's null parser accepts only the exact lowercase literal 'null' at the current position; any other token raises this IllegalArgumentException. JSON null must be lowercase — 'None', 'NULL', or 'nil' are not valid.

Solutions

  1. Replace the token with the lowercase JSON literal null
  2. Use a proper serializer (Python: json.dumps, Java: Jackson) so None/NULL becomes null automatically
  3. Check the reported position to identify which invalid null token appeared
  4. Fix template/code that interpolates database NULLs directly into JSON

Example fix

// before
String json = "{\"value\":None}"; // Python repr
// after
String json = "{\"value\":null}";
Defensive patterns

Strategy: validation

Validate before calling

if (json.matches(".*:\\s*(None|NULL|Nil)\\s*[,}\\]].*")) {
    throw new IllegalArgumentException("Non-JSON null literal found; use lowercase null");
}

Try / catch

try {
    String result = CopilotToolProcessor.jsonToMapOfSource(json);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Expected null")) {
        // replace None/NULL/Nil with null and retry
    }
}

Prevention

When it happens

Trigger: Parsing JSON containing 'None' (Python), 'NULL' (SQL/other languages), 'Nil', or an empty token where null is expected, e.g. '{"value":None}'.

Common situations: Serializing Python objects with str()/repr() instead of json.dumps (which turns None into null); templates that substitute NULL from SQL; hand-written JSON copying another language's null keyword.

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/164f429b197d6495. Report an issue: GitHub.

Appendix: source

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

        private String parseBoolean() {
            if (input.startsWith("true", pos)) {
                pos += 4;
                return "true";
            }
            if (input.startsWith("false", pos)) {
                pos += 5;
                return "false";
            }
            throw new IllegalArgumentException("Expected boolean at position " + pos);
        }

        private String parseNull() {
            if (input.startsWith("null", pos)) {
                pos += 4;
                return "(Object) null";
            }
            throw new IllegalArgumentException("Expected null at position " + pos);
        }

        private String parseNumber() {
            int start = pos;
            if (pos < input.length() && input.charAt(pos) == '-') {
                pos++;
            }
            if (pos >= input.length()) {
                throw new IllegalArgumentException("Expected number at position " + start);
            }
            if (input.charAt(pos) == '0') {
                pos++;
            } else if (isDigitOneToNine(input.charAt(pos))) {
                consumeDigits();
            } else {
                throw new IllegalArgumentException("Expected number at position " + pos);
            }
            if (pos < input.length() && input.charAt(pos) == '.') {

View on GitHub (pinned to cd8cf15dc3)