{"record":{"id":"4fddf34d9d939fe5","repo":"conductor-oss/conductor","slug":"failed-to-read-inputstream-for-upload","errorCode":null,"errorMessage":"Failed to read InputStream for upload","messagePattern":"Failed to read InputStream for upload","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/document/DocumentLoader.java","lineNumber":38,"sourceCode":"public interface DocumentLoader {\n\n    byte[] download(String location);\n\n    String upload(Map<String, String> headers, String contentType, byte[] data, String fileURI);\n\n    /**\n     * Upload data from an InputStream, allowing streaming of large files (e.g., video) without\n     * buffering the entire content in memory.\n     *\n     * <p>Default implementation reads all bytes into memory and delegates to the byte[]-based\n     * upload. Implementations should override this for true streaming behavior.\n     */\n    default String upload(\n            Map<String, String> headers, String contentType, InputStream data, String fileURI) {\n        try {\n            return upload(headers, contentType, data.readAllBytes(), fileURI);\n        } catch (IOException e) {\n            throw new RuntimeException(\"Failed to read InputStream for upload\", e);\n        }\n    }\n\n    List<String> listFiles(String location);\n\n    boolean supports(String location);\n}\n","sourceCodeStart":20,"sourceCodeEnd":46,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/document/DocumentLoader.java#L20-L46","documentation":"Thrown by the default DocumentLoader.upload(Map,String,InputStream,String) when InputStream.readAllBytes() raises an IOException. The default implementation buffers the whole stream into memory then delegates to the byte[]-based upload; this exception means the stream itself was unreadable, not that the upload failed. RuntimeException wrapping the IOException.","triggerScenarios":"A closed, already-consumed, or broken InputStream is passed to upload(); the underlying source throws during read (e.g. a socket/pipe that closed, a truncated file, a stream from a resource that was freed).","commonSituations":"Reusing a stream that was already read once; passing a stream from a try-with-resources that has been closed; reading from a network/socket source that drops mid-transfer; very large streams failing on memory exhaustion during readAllBytes.","solutions":["Ensure the InputStream is open, at position 0, and readable when passed (do not double-consume or pass a closed stream).","For large files, override upload(...) in your DocumentLoader to stream instead of buffering (avoid readAllBytes entirely).","Wrap the source so read failures surface a meaningful cause; check getCause() for the real IOException.","If memory is the issue (huge files), use a streaming implementation rather than the default in-memory one."],"exampleFix":"// before — stream already used\nInputStream is = Files.newInputStream(path);\nis.readAllBytes();\nloader.upload(headers, ct, is, uri); // closed/exhausted -> error\n// after — fresh stream\nloader.upload(headers, ct, Files.newInputStream(path), uri);","handlingStrategy":"validation","validationCode":"// Ensure the stream is fresh and readable before upload\nif (data == null) throw new IllegalArgumentException(\"InputStream is null\");\n// best: open a new stream per call, e.g. Files.newInputStream(path)\nloader.upload(headers, contentType, Files.newInputStream(path), fileURI);","typeGuard":null,"tryCatchPattern":"try {\n    loader.upload(headers, contentType, inputStream, fileURI);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof java.io.IOException io) {\n        log.error(\"Could not read upload stream: {}\", io.getMessage());\n    }\n    throw e;\n}","preventionTips":["Never reuse a stream that has already been read or closed.","Open a fresh InputStream per upload call.","For large files, implement a streaming upload(...) override instead of relying on the in-memory default."],"tags":["document-loader","upload","io","inputstream","runtimeexception"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}