{"id":"750de0e83fd58ce6","repo":"google/gson","slug":"message-locationstring-see-troubleshootin","errorCode":null,"errorMessage":"${message}${locationString()}\nSee ${TroubleshootingGuide.createUrl(\"malformed-json\")}","messagePattern":"\\$\\{message\\}\\$\\{locationString\\(\\)\\}\nSee \\$\\{TroubleshootingGuide\\.createUrl\\(\"malformed-json\"\\)\\}","errorType":"exception","errorClass":"MalformedJsonException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonReader.java","lineNumber":1840,"sourceCode":"        if (strictness == Strictness.STRICT) {\n          throw syntaxError(\"Invalid escaped character \\\"'\\\" in strict mode\");\n        }\n      case '\"':\n      case '\\\\':\n      case '/':\n        return escaped;\n      default:\n        // throw error when none of the above cases are matched\n        throw syntaxError(\"Invalid escape sequence\");\n    }\n  }\n\n  /**\n   * Throws a new {@link MalformedJsonException} with the given message and information about the\n   * current location.\n   */\n  private MalformedJsonException syntaxError(String message) throws MalformedJsonException {\n    throw new MalformedJsonException(\n        message + locationString() + \"\\nSee \" + TroubleshootingGuide.createUrl(\"malformed-json\"));\n  }\n\n  private IllegalStateException unexpectedTokenError(String expected) throws IOException {\n    JsonToken peeked = peek();\n    String troubleshootingId =\n        peeked == JsonToken.NULL ? \"adapter-not-null-safe\" : \"unexpected-json-structure\";\n    return new IllegalStateException(\n        \"Expected \"\n            + expected\n            + \" but was \"\n            + peek()\n            + locationString()\n            + \"\\nSee \"\n            + TroubleshootingGuide.createUrl(troubleshootingId));\n  }\n\n  /** Consumes the non-execute prefix if it exists. */","sourceCodeStart":1822,"sourceCodeEnd":1858,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/stream/JsonReader.java#L1822-L1858","documentation":"This is the single construction site in JsonReader.syntaxError(String): it builds a MalformedJsonException (an IOException subclass) whose message is '<reason> at line L column C path $...' plus a link to the malformed-json troubleshooting page. Nearly every JSON grammar violation in JsonReader is routed through this method, so the visible message is the reason text (e.g. 'Unterminated string', 'Expected name', 'JSON forbids NaN and infinities', 'Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON'). The location string pinpoints where in the input the parser failed.","triggerScenarios":"Any malformed input to JsonReader: unterminated array/object/string (lines 598, 614, 1192, 1281, 1595), expected name/colon/value (631, 640, 657, 694, 724), NaN/Infinity literal in non-LENIENT mode (1063), invalid escape sequence or malformed \\u (1771, 1778, 1792, 1815, 1823, 1831), strict-mode unquoted strings/comments (checkLenient, 1637), non-ASCII in strict strings (1884). Also fires when nextDouble() encounters NaN/Infinity and strictness != LENIENT.","commonSituations":"Reading truncated network responses; parsing JSON produced by lenient writers that emitted NaN/Infinity, comments, single-quoted strings, or unquoted keys; feeding concatenated NDJSON to one JsonReader; corrupted files with stray BOM/control characters; version skew where a producer uses LENIENT features the consumer (default LEGACY_STRICT) rejects; BOM or trailing data after the root value.","solutions":["Inspect the message reason text and location (line/column/path) to find the exact bad token, then fix the producer.","If the input intentionally uses lenient syntax (comments, unquoted keys, NaN), call reader.setStrictness(Strictness.LENIENT) before reading.","Validate/prettify the payload with a strict parser upstream, or run it through JsonReader in LENIENT then re-emit canonical JSON.","For truncated streaming input, ensure the source writes complete JSON before the reader consumes it; for NDJSON, create a new JsonReader per line/document."],"exampleFix":"// before\ntry (JsonReader reader = new JsonReader(new StringReader(payload))) {\n  reader.beginObject(); // throws MalformedJsonException on bad token\n}\n\n// after: tolerate lenient producer + handle parse failure\ntry (JsonReader reader = new JsonReader(new StringReader(payload))) {\n  reader.setStrictness(Strictness.LENIENT);\n  reader.beginObject();\n} catch (MalformedJsonException e) {\n  log.warn(\"Unparseable JSON payload: {}\", e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate JSON with a strict parser before handing off, or set LENIENT for tolerant reads\npublic JsonReader lenientReader(String payload) {\n  JsonReader r = new JsonReader(new StringReader(payload));\n  r.setStrictness(Strictness.LENIENT); // accept comments, unquoted keys, NaN, etc.\n  return r;\n}","typeGuard":"// Cheap structural pre-check before full parse: balanced brackets and non-empty\npublic boolean looksLikeCompleteJson(String s) {\n  if (s == null || s.isBlank()) return false;\n  int depth = 0; boolean inStr = false; boolean esc = false;\n  for (int i = 0; i < s.length(); i++) {\n    char c = s.charAt(i);\n    if (esc) { esc = false; continue; }\n    if (c == '\\\\') { esc = true; continue; }\n    if (c == '\"') { inStr = !inStr; continue; }\n    if (inStr) continue;\n    if (c == '{' || c == '[') depth++;\n    else if (c == '}' || c == ']') depth--;\n  }\n  return !inStr && depth == 0;\n}","tryCatchPattern":"try (JsonReader reader = new JsonReader(source)) {\n  // ... parse ...\n} catch (MalformedJsonException e) {\n  // message includes reason + 'at line L column C path $...' + troubleshooting URL\n  throw new MyParseException(\"Bad JSON at \" + extractLocation(e.getMessage()), e);\n}","preventionTips":["Set Strictness.LENIENT on JsonReader when consuming input that may use comments, unquoted keys, single quotes, or NaN literals.","For NDJSON, create a fresh JsonReader per line/document rather than feeding the whole stream to one reader.","Validate producer output with a strict parser in tests/CI so malformed payloads are caught before deployment.","Use the line/column/path in the exception message to localize the defect, then fix the producer rather than silencing the error.","Guard against truncated network responses by checking Content-Length / read completeness before parsing."],"tags":["json","gson","parsing","malformed","strictness"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}