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
- Replace the token with the lowercase JSON literal null
- Use a proper serializer (Python: json.dumps, Java: Jackson) so None/NULL becomes null automatically
- Check the reported position to identify which invalid null token appeared
- 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
- JSON null is lowercase only; other languages' nulls must be converted (Python json.dumps maps None->null)
- Never interpolate SQL NULL directly into JSON strings
- Use proper serializers so null handling is automatic
- Validate hand-written JSON with a reference parser
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
- Expected boolean at position
- Expected number at position
- Expected number at position
- Incomplete Unicode escape at position <pos-2>
- Invalid escape sequence \
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)