conductor-oss/conductor · error · RuntimeException
Failed to read InputStream for upload
Error message
Failed to read InputStream for upload
What it means
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.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/document/DocumentLoader.java:38
public interface DocumentLoader {
byte[] download(String location);
String upload(Map<String, String> headers, String contentType, byte[] data, String fileURI);
/**
* Upload data from an InputStream, allowing streaming of large files (e.g., video) without
* buffering the entire content in memory.
*
* <p>Default implementation reads all bytes into memory and delegates to the byte[]-based
* upload. Implementations should override this for true streaming behavior.
*/
default String upload(
Map<String, String> headers, String contentType, InputStream data, String fileURI) {
try {
return upload(headers, contentType, data.readAllBytes(), fileURI);
} catch (IOException e) {
throw new RuntimeException("Failed to read InputStream for upload", e);
}
}
List<String> listFiles(String location);
boolean supports(String location);
}
View on GitHub (pinned to cf7c3e4a8a)
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.
Example fix
// before — stream already used InputStream is = Files.newInputStream(path); is.readAllBytes(); loader.upload(headers, ct, is, uri); // closed/exhausted -> error // after — fresh stream loader.upload(headers, ct, Files.newInputStream(path), uri);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the stream is fresh and readable before upload
if (data == null) throw new IllegalArgumentException("InputStream is null");
// best: open a new stream per call, e.g. Files.newInputStream(path)
loader.upload(headers, contentType, Files.newInputStream(path), fileURI); Try / catch
try {
loader.upload(headers, contentType, inputStream, fileURI);
} catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof java.io.IOException io) {
log.error("Could not read upload stream: {}", io.getMessage());
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- error uploading file %s - %s
- Error making an HTTP call {reasonPhrase}, status: {statusCod
- Failed to read skill file: {e.getMessage()}
- Failed to read skill package: {e.getMessage()}
- OAuth token request failed: HTTP {code}
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/4fddf34d9d939fe5.
Report an issue: GitHub.