flowable/flowable-engine · error · FlowableException

inputStream for resource '${resourceName}' is null

Error message

inputStream for resource '${resourceName}' is null

What it means

DmnDeploymentBuilderImpl.addInputStream requires a non-null InputStream to build the DMN deployment resource. Passing null means no bytes can be stored for the named resource, so Flowable fails fast with a FlowableException. This is a caller-side argument error, not a deployment failure.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/repository/DmnDeploymentBuilderImpl.java:57

    protected transient DmnRepositoryServiceImpl repositoryService;
    protected transient DmnResourceEntityManager resourceEntityManager;

    protected DmnDeploymentEntity deployment;
    protected boolean isDmn20XsdValidationEnabled = true;
    protected boolean isDuplicateFilterEnabled;

    public DmnDeploymentBuilderImpl() {
        DmnEngineConfiguration dmnEngineConfiguration = CommandContextUtil.getDmnEngineConfiguration();
        this.repositoryService = (DmnRepositoryServiceImpl) dmnEngineConfiguration.getDmnRepositoryService();
        this.deployment = dmnEngineConfiguration.getDeploymentEntityManager().create();
        this.resourceEntityManager = dmnEngineConfiguration.getResourceEntityManager();
    }

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

        byte[] bytes = null;
        try {
            bytes = IOUtils.toByteArray(inputStream);
        } 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");
        }

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

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the resource actually exists on the classpath: try (InputStream is = getClass().getResourceAsStream(path)) { assert is != null; } and fix the path (leading slash, package directory) if null.
  2. Check your build config (Maven <resources> / Gradle processResources) includes *.dmn files so they land in the jar.
  3. Null-check or use Objects.requireNonNull(inputStream) before calling addInputStream to get a clearer stack trace at your call site.
  4. Use addClasspathResource with a corrected classpath location, or read via Files.newInputStream(Paths.get(file)) for filesystem resources.

Example fix

// before
InputStream is = getClass().getResourceAsStream("decision.dmn"); // null: wrong path
builder.addInputStream("decision.dmn", is);

// after
String path = "/diagrams/decision.dmn";
InputStream is = getClass().getResourceAsStream(path);
if (is == null) throw new IllegalStateException("Resource not on classpath: " + path);
builder.addInputStream("decision.dmn", is);
Defensive patterns

Strategy: type-guard

Validate before calling

String path = "/diagrams/decision.dmn";
try (InputStream is = getClass().getResourceAsStream(path)) {
    if (is == null) throw new IllegalArgumentException("DMN resource missing from classpath: " + path);
}

Type guard

function hasResource(String path) {
    try (InputStream is = getClass().getResourceAsStream(path)) {
        return is != null;
    } catch (IOException e) { return false; }
}

Try / catch

try {
    builder.addInputStream(name, inputStream);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("inputStream for resource")) {
        // stream was null: re-open resource or fail deployment with clear message
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling dmnRepositoryService.createDeployment().addInputStream(name, is) with a null stream — typically when a prior getResourceAsStream(name) on the classpath returned null, or a variable holding the stream was never initialized. addClasspathResource delegates to addInputStream, so a classpath resource that does not exist surfaces here too.

Common situations: Typo in the .dmn XML resource path inside src/main/resources; resource not copied into the artifact (missing Maven resource include); reading from a closed/failed loader that returned null instead of throwing; CI packaging excludes the resource directory.

Related errors


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