{"record":{"id":"d7cc8ea10d7e083b","repo":"google/gson","slug":"end-of-input","errorCode":null,"errorMessage":"End of input{}","messagePattern":"End of input(.+?)","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonReader.java","lineNumber":1629,"sourceCode":"        }\n      } else if (c == '#') {\n        pos = p;\n        /*\n         * Skip a # hash end-of-line comment. The JSON RFC doesn't\n         * specify this behavior, but it's required to parse\n         * existing documents. See http://b/2571423.\n         */\n        checkLenient();\n        skipToEndOfLine();\n        p = pos;\n        l = limit;\n      } else {\n        pos = p;\n        return c;\n      }\n    }\n    if (throwOnEof) {\n      throw new EOFException(\"End of input\" + locationString());\n    } else {\n      return -1;\n    }\n  }\n\n  private void checkLenient() throws MalformedJsonException {\n    if (strictness != Strictness.LENIENT) {\n      throw syntaxError(\n          \"Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON\");\n    }\n  }\n\n  /**\n   * Advances the position until after the next newline character. If the line is terminated by\n   * \"\\r\\n\", the '\\n' must be consumed as whitespace by the caller.\n   */\n  private void skipToEndOfLine() throws IOException {\n    while (pos < limit || fillBuffer(1)) {","sourceCodeStart":1611,"sourceCodeEnd":1647,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonReader.java#L1611-L1647","documentation":"Thrown by JsonReader.nextNonWhitespace(true) as an EOFException (JsonReader.java:1628-1629) when the reader needs another non-whitespace character but fillBuffer returns false because the underlying stream is exhausted. The throwOnEof=true call sites are the structural readers (begin/end, doPeek value discovery) that require a token; reaching EOF mid-structure means the JSON is truncated or incomplete.","triggerScenarios":"Calling beginObject/beginArray/nextName/etc. when the stream ends prematurely (e.g. JSON cut off mid-object, an empty or blank document, a network read truncated). Also when hasNext is not used and the loop assumes more tokens exist.","commonSituations":"Truncated HTTP responses; streaming over sockets that close early; empty input passed to a parser expecting an object; partial writes from a producer; forgetting to handle the END_DOCUMENT token from peek().","solutions":["Check peek()==JsonToken.END_DOCUMENT before consuming tokens.","Use hasNext() in loops instead of fixed counts.","Validate the source is complete (Content-Length, checksum) before parsing.","Catch EOFException at the parse boundary and map it to a domain error (e.g. 'incomplete payload')."],"exampleFix":"// before\nreader.beginObject();\nString n = reader.nextName(); // throws EOFException on empty input\n\n// after\nif (reader.peek() == JsonToken.END_DOCUMENT) {\n  return null;\n}\nreader.beginObject();","handlingStrategy":"try-catch","validationCode":"if (reader.peek() == JsonToken.END_DOCUMENT) {\n  return Optional.empty();\n}\nreader.beginObject();\n...","typeGuard":"static boolean hasMore(JsonReader r) throws IOException {\n  return r.peek() != JsonToken.END_DOCUMENT;\n}","tryCatchPattern":"try {\n  reader.beginObject();\n} catch (EOFException e) {\n  return null; // or a domain 'empty input' result\n}","preventionTips":["Always check peek()/hasNext() before consuming tokens.","Validate payload completeness (Content-Length, EOF) before parsing.","Wrap parse entry points to translate EOFException into domain errors."],"tags":["java","gson","jsonreader","eof","parsing"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}