{"record":{"id":"73f263b4df2b2a24","repo":"github/copilot-sdk","slug":"unterminated-string-escape-at-position-pos","errorCode":null,"errorMessage":"Unterminated string escape at position <pos>","messagePattern":"Unterminated string escape at position <pos>","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java","lineNumber":1044,"sourceCode":"            StringBuilder sb = new StringBuilder();\n            while (pos < input.length() && input.charAt(pos) != '\"') {\n                char current = input.charAt(pos++);\n                if (current == '\\\\') {\n                    sb.append(parseEscape());\n                } else {\n                    if (current < 0x20) {\n                        throw new IllegalArgumentException(\"Unescaped control character at position \" + (pos - 1));\n                    }\n                    sb.append(current);\n                }\n            }\n            expect('\"');\n            return sb.toString();\n        }\n\n        private char parseEscape() {\n            if (pos >= input.length()) {\n                throw new IllegalArgumentException(\"Unterminated string escape at position \" + pos);\n            }\n            char escaped = input.charAt(pos++);\n            return switch (escaped) {\n                case '\"', '\\\\', '/' -> escaped;\n                case 'b' -> '\\b';\n                case 'f' -> '\\f';\n                case 'n' -> '\\n';\n                case 'r' -> '\\r';\n                case 't' -> '\\t';\n                case 'u' -> parseUnicodeEscape();\n                default -> throw new IllegalArgumentException(\n                        \"Invalid escape sequence \\\\\" + escaped + \" at position \" + (pos - 2));\n            };\n        }\n\n        private char parseUnicodeEscape() {\n            if (pos + 4 > input.length()) {\n                throw new IllegalArgumentException(\"Incomplete Unicode escape at position \" + (pos - 2));","sourceCodeStart":1026,"sourceCodeEnd":1062,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/tool/CopilotToolProcessor.java#L1026-L1062","documentation":"parseEscape is invoked after a backslash inside a JSON string, but the input has already ended — the backslash was the last character, so no escape character follows. This means the string literal is truncated/malformed, and the converter reports the position of the dangling escape.","triggerScenarios":"A JSON string ending in a lone backslash, e.g. '{\"path\":\"C:\\\\' where the final backslash is not itself escaped (should be '\\\\\\\\'), or a truncated string from a cut-off network payload.","commonSituations":"Windows file paths embedded in JSON where backslashes were not doubled; manually escaped strings where the trailing backslash was missed; truncated responses from a flaky stream or log capture.","solutions":["Escape backslashes properly: every literal \\ in a JSON string must be written as \\\\ (so a path ending in \\ becomes ...\\\\\\\\)","Use a JSON serializer to build the string instead of manual escaping","Check whether the payload was truncated in transit or by logging; re-fetch the complete payload","Fix any hand-rolled escaping/unescape code that strips one backslash too many"],"exampleFix":"// before\nString json = \"{\\\"path\\\":\\\"C:\\\\tmp\\\\\\\"}\"; // trailing single backslash\n// after\nString json = \"{\\\"path\\\":\\\"C:\\\\tmp\\\\\\\"}\".replace(\"\\\\\\\\\\\"\", \"\\\\\\\\\\\\\\\\\\\"\");\n// better: serialize with a JSON library\nString json = new JSONObject().put(\"path\", \"C:\\tmp\\\\\").toString();","handlingStrategy":"validation","validationCode":"if (json.trim().endsWith(\"\\\\\")) {\n    throw new IllegalArgumentException(\"Payload ends with a dangling backslash; escaping is broken or input truncated\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String result = CopilotToolProcessor.jsonToMapOfSource(json);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Unterminated string escape\")) {\n        // check payload completeness / re-encode backslashes\n    }\n}","preventionTips":["Double every literal backslash in JSON strings (Windows paths: C:\\\\ -> C:\\\\\\\\)","Use a JSON serializer for anything containing backslashes","Verify payloads were not truncated by log buffers or network reads","Never hand-strip escapes before parsing"],"tags":["java","json","parsing","escaping"],"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"}