flowable/flowable-engine · error · FlowableException

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

Error message

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

What it means

CmmnDeploymentBuilderImpl.addInputStream throws FlowableException with "byte array for resource '<resourceName>' is null" when IoUtil.readInputStream returns null instead of the expected byte array. This is a defensive post-read check: the stream appeared readable but yielded no content, so the deployment resource would be empty.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/repository/CmmnDeploymentBuilderImpl.java:63

        this.deployment = cmmnEngineConfiguration.getCmmnDeploymentEntityManager().create();
        this.resourceEntityManager = cmmnEngineConfiguration.getCmmnResourceEntityManager();
    }

    @Override
    public CmmnDeploymentBuilder 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");
        }

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

    @Override
    public CmmnDeploymentBuilder 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);
            
        } catch (IOException ex) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the source actually has content before adding it (file size > 0, stream available()).
  2. Replace degenerate stream implementations (mocks, custom wrappers) with real byte-producing streams like ByteArrayInputStream.
  3. If reading manually, validate the byte array is non-null and non-empty before deploying.

Example fix

// before
builder.addInputStream(name, maybeBrokenStream);

// after
byte[] bytes = IoUtil.readInputStream(maybeBrokenStream, name);
if (bytes == null || bytes.length == 0) {
    throw new IllegalStateException("resource is empty: " + name);
}
builder.addInputStream(name, new ByteArrayInputStream(bytes));
Defensive patterns

Strategy: validation

Validate before calling

byte[] bytes = IoUtil.readInputStream(is, name);
if (bytes == null || bytes.length == 0) {
    throw new IllegalStateException("resource has no content: " + name);
}
builder.addInputStream(name, new ByteArrayInputStream(bytes));

Type guard

boolean hasContent(byte[] b) { return b != null && b.length > 0; }

Try / catch

try {
    builder.addInputStream(name, is);
} catch (FlowableException e) {
    if (!e.getMessage().contains("is null")) throw e;
    throw new DeploymentException("empty resource: " + name, e);
}

Prevention

When it happens

Trigger: addInputStream called with a stream whose read produces a null byte result — practically a stream reporting no content (e.g. a degenerate/unusable stream implementation) — via addInputStream or addClasspathResource.

Common situations: Custom or mocked InputStream implementations returning null; reading from an empty or zero-length file/source; a wrapper stream that silently returns nothing instead of throwing.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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