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.

Solutions

  1. Ensure the InputStream is open, at position 0, and readable when passed (do not double-consume or pass a closed stream).
  2. For large files, override upload(...) in your DocumentLoader to stream instead of buffering (avoid readAllBytes entirely).
  3. Wrap the source so read failures surface a meaningful cause; check getCause() for the real IOException.
  4. 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

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


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/4fddf34d9d939fe5. Report an issue: GitHub.

Appendix: 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)