flowable/flowable-engine · error · FlowableObjectNotFoundException

Could not find a deployment with id '<deploymentId>

Error message

Could not find a deployment with id '<deploymentId>

What it means

Thrown by HistoricTaskInstanceQuery.taskAssigneeIds(Collection) when the assignee collection is non-null but contains no elements. An empty IN clause is invalid SQL, so the builder rejects empty lists explicitly. At least one assignee id must be supplied.

Source

Thrown at modules/flowable-app-engine-rest/src/main/java/org/flowable/app/rest/service/api/repository/AppDefinitionResourceDataResource.java:80

        if (appDefinition == null) {
            throw new FlowableObjectNotFoundException("Could not find an app definition with id '" + appDefinitionId);
        }
        if (appDefinition.getDeploymentId() == null) {
            throw new FlowableException("No deployment id available");
        }
        if (appDefinition.getResourceName() == null) {
            throw new FlowableException("No resource name available");
        }
        
        if (restApiInterceptor != null) {
            restApiInterceptor.accessAppDefinitionInfoById(appDefinition);
        }

        // Check if deployment exists
        AppDeployment deployment = appRepositoryService.createDeploymentQuery().deploymentId(appDefinition.getDeploymentId()).singleResult();
        if (deployment == null) {
            throw new FlowableObjectNotFoundException("Could not find a deployment with id '" + appDefinition.getDeploymentId());
        }

        List<String> resourceList = appRepositoryService.getDeploymentResourceNames(appDefinition.getDeploymentId());

        if (resourceList.contains(appDefinition.getResourceName())) {
            final InputStream resourceStream = appRepositoryService.getResourceAsStream(
                    appDefinition.getDeploymentId(), appDefinition.getResourceName());

            response.setContentType("application/json");
            try {
                return IOUtils.toByteArray(resourceStream);
            } catch (Exception e) {
                throw new FlowableException("Error converting resource stream", e);
            }
            
        } else {
            // Resource not found in deployment
            throw new FlowableObjectNotFoundException("Could not find a resource with id '" +

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Guard with !assignees.isEmpty() before calling taskAssigneeIds; omit the filter when empty.
  2. Return an empty query result early (don't execute the query) when there are no assignees to filter by.
  3. Ensure upstream logic only invokes the query builder when at least one assignee id exists.

Example fix

// before
query.taskAssigneeIds(assignees); // can be empty

// after
if (assignees != null && !assignees.isEmpty()) {
    query.taskAssigneeIds(assignees);
}
Defensive patterns

Strategy: validation

Validate before calling

if (assignees == null || assignees.isEmpty()) {
    return Collections.emptyList(); // nothing to filter by
}
query.taskAssigneeIds(assignees);

Type guard

static boolean isApplicable(Collection<String> c) { return c != null && !c.isEmpty(); }

Try / catch

try {
    query.taskAssigneeIds(assignees);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("empty")) { return Collections.emptyList(); }
    throw e;
}

Prevention

When it happens

Trigger: Calling taskAssigneeIds(new ArrayList<>()) / List.of(), or passing a collection that became empty after filtering (e.g., removing deactivated users left nothing).

Common situations: A multi-select with no users chosen; a team with zero members; a stream().filter(...) that removed all entries before the query is built.

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/8f12fb90af700c82. Report an issue: GitHub.