flowable/flowable-engine · error · FlowableIllegalArgumentException

bytes is null

Error message

bytes is null

What it means

Flowable's DeploymentBuilder.addBytes attaches a raw byte array as a deployment resource. It throws FlowableIllegalArgumentException when the byte array is null, since a resource must have content to persist. This is a simple argument validation guard.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/repository/DeploymentBuilderImpl.java:105

    }

    @Override
    public DeploymentBuilder addString(String resourceName, String text) {
        if (text == null) {
            throw new FlowableIllegalArgumentException("text is null");
        }
        ResourceEntity resource = resourceEntityManager.create();
        resource.setName(resourceName);
        resource.setBytes(text.getBytes(StandardCharsets.UTF_8));
        deployment.addResource(resource);
        return this;
    }

    @Override
    public DeploymentBuilder addBytes(String resourceName, byte[] bytes) {
        if (bytes == null) {
            throw new FlowableIllegalArgumentException("bytes is null");
        }
        ResourceEntity resource = resourceEntityManager.create();
        resource.setName(resourceName);
        resource.setBytes(bytes);

        deployment.addResource(resource);
        return this;
    }

    @Override
    public DeploymentBuilder addZipInputStream(ZipInputStream zipInputStream) {
        try {
            ZipEntry entry = zipInputStream.getNextEntry();
            while (entry != null) {
                if (!entry.isDirectory()) {
                    String entryName = entry.getName();
                    byte[] bytes = IoUtil.readInputStream(zipInputStream, entryName);
                    ResourceEntity resource = resourceEntityManager.create();

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check the byte array for null before calling addBytes.
  2. Fix the upstream producer of the bytes (file read, decode, service call) so it returns actual content or fails with a clear error.
  3. If the resource is genuinely optional, skip calling addBytes instead of passing null.

Example fix

// before
byte[] modelBytes = readModelBytes(name); // may be null
repositoryService.createDeployment().addBytes(name, modelBytes).deploy();
// after
byte[] modelBytes = readModelBytes(name);
if (modelBytes != null) {
    repositoryService.createDeployment().addBytes(name, modelBytes).deploy();
} else {
    throw new IllegalStateException("Model bytes missing for " + name);
}
Defensive patterns

Strategy: validation

Validate before calling

if (bytes == null || bytes.length == 0) throw new IllegalArgumentException("resource bytes for " + resourceName + " missing");

Type guard

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

Try / catch

try {
    builder.addBytes(name, bytes).deploy();
} catch (FlowableIllegalArgumentException e) {
    log.error("addBytes rejected null content for {}", name);
    throw e;
}

Prevention

When it happens

Trigger: Calling deploymentBuilder.addBytes(resourceName, null); passing a byte[] returned from a failed read/encode step (e.g. Files.readAllBytes failed upstream, Base64 decode of a null property).

Common situations: Loading model files from disk or database where the fetch returned null; externalized configuration that did not resolve; frameworks injecting optional byte content that is absent in the target environment.

Related errors


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