{"record":{"id":"b066dcbdcf8b1544","repo":"google/gson","slug":"jsonreader-is-closed-b066dc","errorCode":null,"errorMessage":"JsonReader is closed","messagePattern":"JsonReader is closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonReader.java","lineNumber":674,"sourceCode":"        default:\n          throw syntaxError(\"Expected ':'\");\n      }\n    } else if (peekStack == JsonScope.EMPTY_DOCUMENT) {\n      if (strictness == Strictness.LENIENT) {\n        consumeNonExecutePrefix();\n      }\n      stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT;\n    } else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) {\n      int c = nextNonWhitespace(false);\n      if (c == -1) {\n        peeked = PEEKED_EOF;\n        return peeked;\n      } else {\n        checkLenient();\n        pos--;\n      }\n    } else if (peekStack == JsonScope.CLOSED) {\n      throw new IllegalStateException(\"JsonReader is closed\");\n    }\n\n    int c = nextNonWhitespace(true);\n    switch (c) {\n      case ']':\n        if (peekStack == JsonScope.EMPTY_ARRAY) {\n          peeked = PEEKED_END_ARRAY;\n          return peeked;\n        }\n      // fall-through to handle \",]\"\n      case ';':\n      case ',':\n        // In lenient mode, a 0-length literal in an array means 'null'.\n        if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) {\n          checkLenient();\n          pos--;\n          peeked = PEEKED_NULL;\n          return peeked;","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonReader.java#L656-L692","documentation":"Thrown by JsonReader.doPeek() when the top of the scope stack is JsonScope.CLOSED (JsonReader.java:673-675). After close() is called the reader sets stack[0]=CLOSED, so any subsequent read attempt (peek, hasNext, next*, begin*/end*) routes through doPeek and fails with this IllegalStateException. It prevents reads against a released reader whose underlying stream is gone.","triggerScenarios":"Calling any read method after reader.close(); using a reader inside a try-with-resources and then reading in a finally block or a callback that runs after close; sharing a reader instance that another thread or method already closed.","commonSituations":"try-with-resources that closes the reader before a deferred read; helper methods that close the reader and return a value the caller then tries to extend; reusing a reader field across multiple parse operations.","solutions":["Do not read after close(); perform all reads before closing.","If you need the data after close, materialize it into POJOs/strings first, then close.","Track a closed flag in your wrapper and short-circuit reads.","Avoid sharing a single JsonReader across operations; create a fresh one per stream."],"exampleFix":"// before\ntry (JsonReader r = new JsonReader(reader)) {\n  return r.peek();\n}\n// later caller calls nextString() on the closed reader\n\n// after\nString value;\ntry (JsonReader r = new JsonReader(reader)) {\n  value = r.nextString();\n}\nreturn value;","handlingStrategy":"validation","validationCode":"// Read everything needed before closing; do not read after close.\nList<String> vals = new ArrayList<>();\nreader.beginArray();\nwhile (reader.hasNext()) vals.add(reader.nextString());\nreader.endArray();\nreader.close();\n// use `vals` after close, not `reader`","typeGuard":"// JsonReader has no public isOpen(); track closure in a wrapper.\nclass SafeJsonReader {\n  private final JsonReader r;\n  private boolean closed;\n  boolean isOpen() { return !closed; }\n  void close() throws IOException { r.close(); closed = true; }\n}","tryCatchPattern":"try {\n  reader.nextString();\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"closed\")) return null;\n  throw e;\n}","preventionTips":["Materialize data into POJOs/strings before close.","Never share a JsonReader across operations or threads.","Scope close() at the outermost layer so nothing reads after."],"tags":["java","gson","jsonreader","lifecycle","resource-management"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}