{"record":{"id":"220b129d307ea599","repo":"github/copilot-sdk","slug":"unexpected-end-of-json","errorCode":null,"errorMessage":"Unexpected end of JSON","messagePattern":"Unexpected end of JSON","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java","lineNumber":1170,"sourceCode":"        }\n\n        private boolean isDigitOneToNine(char c) {\n            return c >= '1' && c <= '9';\n        }\n\n        private void skipWhitespace() {\n            while (pos < input.length() && isJsonWhitespace(input.charAt(pos))) {\n                pos++;\n            }\n        }\n\n        private boolean isJsonWhitespace(char c) {\n            return c == ' ' || c == '\\t' || c == '\\r' || c == '\\n';\n        }\n\n        private char peek() {\n            if (pos >= input.length()) {\n                throw new IllegalArgumentException(\"Unexpected end of JSON\");\n            }\n            return input.charAt(pos);\n        }\n\n        private void expect(char c) {\n            if (pos >= input.length() || input.charAt(pos) != c) {\n                throw new IllegalArgumentException(\"Expected '\" + c + \"' at position \" + pos + \" but got '\"\n                        + (pos < input.length() ? input.charAt(pos) : \"EOF\") + \"'\");\n            }\n            pos++;\n        }\n\n        private boolean tryConsume(char c) {\n            if (pos < input.length() && input.charAt(pos) == c) {\n                pos++;\n                return true;\n            }\n            return false;","sourceCodeStart":1152,"sourceCodeEnd":1188,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java#L1152-L1188","documentation":"CopilotToolProcessor's peek() helper reads the current JSON character but throws IllegalArgumentException if the parser position is past the end of the input. This means the JSON ended abruptly while the parser still expected more content — the input is truncated or empty rather than merely malformed.","triggerScenarios":"Passing an empty string or a JSON prefix (e.g. {\"name\": \"a\", ) to the tool-argument parser; peek() is called when a token or structural character is required but input is exhausted.","commonSituations":"Streaming LLM responses parsed before completion, arguments truncated by a size limit, empty tool-call argument strings from the model.","solutions":["Ensure the full JSON string is received/parsed only after the stream completes.","Check for empty or blank input and short-circuit before invoking the parser.","Catch IllegalArgumentException and treat it as a truncation signal — request regeneration or completion of the tool call."],"exampleFix":"// before\nparse(argsChunk); // partial stream\n// after\nif (argsChunk == null || argsChunk.isBlank()) throw new SkipException();\nString complete = bufferUntilStreamClosed(argsChunk);\nparse(complete);","handlingStrategy":"validation","validationCode":"if (args == null || args.isBlank()) {\n    throw new IllegalStateException(\"Tool arguments are empty — nothing to parse\");\n}","typeGuard":"static boolean hasParseableInput(String s) { return s != null && !s.isBlank(); }","tryCatchPattern":"try {\n    processor.parse(args);\n} catch (IllegalArgumentException e) {\n    if (\"Unexpected end of JSON\".equals(e.getMessage())) {\n        return Result.incomplete(); // wait for stream completion / regenerate\n    }\n    throw e;\n}","preventionTips":["Buffer streaming model output and parse only the complete string.","Enforce a minimum non-blank length on tool-argument payloads.","Set stream-size limits high enough that JSON is never cut mid-way."],"tags":["json","parsing","truncated-input","streaming"],"backgroundTag":"json-parse-error","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}