{"record":{"id":"65b7877f8e4e3630","repo":"spring-projects/spring-ai","slug":"ioexception-wrapped-runtimeexception","errorCode":null,"errorMessage":"IOException (wrapped RuntimeException)","messagePattern":"IOException \\(wrapped RuntimeException\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"spring-ai-commons/src/main/java/org/springframework/ai/reader/JsonReader.java","lineNumber":86,"sourceCode":"\t\tthis.jsonKeysToUse = List.of(jsonKeysToUse);\n\t}\n\n\t@Override\n\tpublic List<Document> get() {\n\t\ttry {\n\t\t\tJsonNode rootNode = JsonMapper.shared().readTree(this.resource.getInputStream());\n\n\t\t\tif (rootNode.isArray()) {\n\t\t\t\treturn StreamSupport.stream(rootNode.spliterator(), true)\n\t\t\t\t\t.map(jsonNode -> parseJsonNode(jsonNode, JsonMapper.shared()))\n\t\t\t\t\t.toList();\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn Collections.singletonList(parseJsonNode(rootNode, JsonMapper.shared()));\n\t\t\t}\n\t\t}\n\t\tcatch (IOException e) {\n\t\t\tthrow new RuntimeException(e);\n\t\t}\n\t}\n\n\tprivate Document parseJsonNode(JsonNode jsonNode, JsonMapper jsonMapper) {\n\t\tMap<String, Object> item = jsonMapper.convertValue(jsonNode, new TypeReference<>() {\n\n\t\t});\n\t\tvar sb = new StringBuilder();\n\n\t\tthis.jsonKeysToUse.stream()\n\t\t\t.filter(item::containsKey)\n\t\t\t.forEach(key -> sb.append(key).append(\": \").append(item.get(key)).append(System.lineSeparator()));\n\n\t\tMap<String, Object> metadata = this.jsonMetadataGenerator.generate(item);\n\t\tString content = sb.isEmpty() ? item.toString() : sb.toString();\n\t\treturn new Document(content, metadata);\n\t}\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/spring-ai-commons/src/main/java/org/springframework/ai/reader/JsonReader.java#L68-L104","documentation":"JsonReader.get() parses the underlying resource as JSON; if reading/parsing the stream throws IOException (unreadable resource, I/O error mid-stream), it is wrapped in a plain RuntimeException. Malformed JSON that Jackson reports as IOException variants (e.g. JsonParseException extends IOException) also lands here.","triggerScenarios":"Calling jsonReader.get() where the Resource input stream fails — file missing, permission denied, connection dropped — or content that Jackson cannot parse (invalid JSON raising JsonParseException).","commonSituations":"Pointing JsonReader at a non-JSON file, truncated downloads, or resources inside a jar with wrong classpath path.","solutions":["Verify resource.exists() and that the content is valid JSON before constructing JsonReader","Validate the JSON with a standalone parse (JsonMapper.shared().readTree) to get richer error details","Catch RuntimeException and inspect the cause for the real IOException/JsonParseException","Log resource.getDescription() to confirm which path was actually resolved"],"exampleFix":"// before\nList<Document> docs = new JsonReader(resource).get(); // RuntimeException on bad content\n// after\nif (!resource.exists()) throw new IllegalStateException(\"Missing: \" + resource);\nJsonMapper.shared().readTree(resource.getInputStream()); // fail early with a clear parse error\nList<Document> docs = new JsonReader(resource).get();","handlingStrategy":"validation","validationCode":"if (!resource.exists()) throw new IllegalStateException(\"Missing JSON: \" + resource);\ntry (InputStream in = resource.getInputStream()) {\n    JsonMapper.shared().readTree(in); // fail fast with a precise Jackson error\n}","typeGuard":null,"tryCatchPattern":"try {\n    docs = jsonReader.get();\n} catch (RuntimeException e) {\n    throw new IllegalStateException(\"JSON read failed: \" + resource, e.getCause());\n}","preventionTips":["Validate JSON files with a linter before ingestion","Check exists()/isReadable() on the resource","Keep resources on stable local storage rather than flaky remote URLs"],"tags":["json","io","reader"],"backgroundTag":"json-parse-error","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}