{"id":"2706ed57eb8d436a","repo":"google/gson","slug":"did-not-consume-the-entire-document","errorCode":null,"errorMessage":"Did not consume the entire document.","messagePattern":"Did not consume the entire document\\.","errorType":"exception","errorClass":"JsonSyntaxException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/JsonParser.java","lineNumber":112,"sourceCode":"\n  /**\n   * Parses the complete JSON string provided by the reader into a parse tree. An exception is\n   * thrown if the JSON string has multiple top-level JSON elements, or if there is trailing data.\n   *\n   * <p>The JSON data is parsed in {@linkplain JsonReader#setStrictness(Strictness) lenient mode}.\n   *\n   * @param reader JSON text\n   * @return a parse tree of {@link JsonElement}s corresponding to the specified JSON\n   * @throws JsonParseException if there is an IOException or if the specified text is not valid\n   *     JSON\n   * @since 2.8.6\n   */\n  public static JsonElement parseReader(Reader reader) throws JsonIOException, JsonSyntaxException {\n    try {\n      JsonReader jsonReader = new JsonReader(reader);\n      JsonElement element = parseReader(jsonReader);\n      if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT) {\n        throw new JsonSyntaxException(\"Did not consume the entire document.\");\n      }\n      return element;\n    } catch (MalformedJsonException | NumberFormatException e) {\n      throw new JsonSyntaxException(e);\n    } catch (IOException e) {\n      throw new JsonIOException(e);\n    }\n  }\n\n  /**\n   * Returns the next value from the JSON stream as a parse tree. Unlike the other {@code parse}\n   * methods, no exception is thrown if the JSON data has multiple top-level JSON elements, or if\n   * there is trailing data.\n   *\n   * <p>If the {@linkplain JsonReader#getStrictness() strictness of the reader} is {@link\n   * Strictness#STRICT}, that strictness will be used for parsing. Otherwise the strictness will be\n   * temporarily changed to {@link Strictness#LENIENT} and will be restored once this method\n   * returns.","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/JsonParser.java#L94-L130","documentation":"JsonParser.parseReader(Reader) parses exactly one top-level JSON value and then verifies the reader is exhausted; if peek() does not return END_DOCUMENT it throws JsonSyntaxException with this message. It guards against concatenated or trailing garbage after the first JSON value, which the lenient parser would otherwise silently accept.","triggerScenarios":"Calling JsonParser.parseReader(new StringReader(\"{}{}\")) or any input with two top-level values, trailing commas/content, or whitespace-separated documents; feeding a stream that contains a value followed by leftover log text.","commonSituations":"Reading NDJSON/log lines as a single document; concatenated API responses in one buffer; copy-paste artifacts (extra brace) in test fixtures; a Reader that was already partially consumed.","solutions":["Use JsonReader.parseReader only on inputs known to contain one top-level value; strip trailing content.","For multiple top-level values, use JsonStreamParser or read repeatedly with JsonReader in a loop.","Validate/trim the string and check for stray characters after the closing token.","Switch to gson.fromJson(json, type) which enforces single-document semantics with clearer errors."],"exampleFix":"// before\nJsonElement e = JsonParser.parseReader(new StringReader(concatenated));\n\n// after (multiple docs)\nJsonStreamParser it = new JsonStreamParser(new StringReader(concatenated));\nwhile (it.hasNext()) {\n  JsonElement e = it.next();\n  // ...\n}","handlingStrategy":"validation","validationCode":"String trimmed = json.trim();\n// verify only one top-level value before parseReader\ntry (JsonReader r = new JsonReader(new StringReader(trimmed))) {\n  r.setStrictness(Strictness.STRICT);\n  // single parse + END_DOCUMENT expectation enforced by parseReader\n}\n","typeGuard":"boolean isSingleDocument(String json) {\n  JsonReader r = new JsonReader(new StringReader(json));\n  try {\n    r.skipValue();\n    return r.peek() == JsonToken.END_DOCUMENT;\n  } catch (Exception ex) { return false; }\n  finally { try { r.close(); } catch (IOException ignored) {} }\n}\n","tryCatchPattern":"try {\n  JsonElement e = JsonParser.parseReader(reader);\n} catch (JsonSyntaxException ex) {\n  if (ex.getMessage().contains(\"Did not consume\")) {\n    // switch to JsonStreamParser for multi-doc input\n  } else throw ex;\n}\n","preventionTips":["Use JsonStreamParser when input may contain multiple top-level values.","Strip trailing whitespace/comments before parsing.","Validate test fixtures contain exactly one JSON value."],"tags":["parsing","malformed-json","strictness"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}