flowable/flowable-engine · error · FlowableException

byte array for resource

Error message

byte array for resource '${resourceName}' is null

What it means

After reading, addInputStream() checks the resulting byte array and throws FlowableException('byte array for resource ... is null') if IoUtil.readInputStream somehow returned null. This is a defensive post-condition: a successful read must always yield bytes, so null indicates a pathological stream implementation.

Solutions

  1. Replace the custom/mocked InputStream with a standard one (ByteArrayInputStream, FileInputStream) that yields real bytes.
  2. Verify the stream's read(byte[], int, int) implementation follows the InputStream contract.
  3. Pre-add the resource bytes yourself via addInputStream(name, new ByteArrayInputStream(data)) to bypass the faulty source.

Example fix

// before
InputStream in = new BrokenMockStream(); // read() returns 0, produces null bytes
deploymentBuilder.addInputStream(name, in);

// after
byte[] data = Files.readAllBytes(Paths.get(filePath));
deploymentBuilder.addInputStream(name, new ByteArrayInputStream(data));
Defensive patterns

Strategy: try-catch

Validate before calling

byte[] data = IoUtil.readInputStream(inputStream, resourceName); if (data == null || data.length == 0) { throw new IllegalStateException("Stream produced no bytes"); }

Try / catch

try { deploymentBuilder.addInputStream(name, in); } catch (FlowableException e) { log.error("Stream for {} yielded no bytes; check stream implementation", name); }

Prevention

When it happens

Trigger: A custom or mock InputStream whose read() methods report data but never actually deliver bytes, or a corrupted/unusual stream implementation that makes IoUtil.readInputStream return null without throwing.

Common situations: Unit tests with hand-rolled or mocked streams that misbehave; exotic stream wrappers (e.g. decompressing streams) that return null results; rarely seen with normal file/classpath streams.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/cdcde398c503f8d5. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDeploymentBuilderImpl.java:62

        this.deployment = appEngineConfiguration.getAppDeploymentEntityManager().create();
        this.resourceEntityManager = appEngineConfiguration.getAppResourceEntityManager();
    }

    @Override
    public AppDeploymentBuilder addInputStream(String resourceName, InputStream inputStream) {
        if (inputStream == null) {
            throw new FlowableException("inputStream for resource '" + resourceName + "' is null");
        }

        byte[] bytes = null;
        try {
            bytes = IoUtil.readInputStream(inputStream, resourceName);
        } catch (Exception e) {
            throw new FlowableException("could not get byte array from resource '" + resourceName + "'", e);
        }

        if (bytes == null) {
            throw new FlowableException("byte array for resource '" + resourceName + "' is null");
        }

        AppResourceEntity resource = resourceEntityManager.create();
        resource.setName(resourceName);
        resource.setBytes(bytes);
        deployment.addResource(resource);
        return this;
    }

    @Override
    public AppDeploymentBuilder addClasspathResource(String resource) {
        try (final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(resource)) {
            if (inputStream == null) {
                throw new FlowableException("resource '" + resource + "' not found");
            }
            
            return addInputStream(resource, inputStream);
            

View on GitHub (pinned to d6d39ce1c6)