flowable/flowable-engine · error · FlowableIllegalArgumentException

baseUrl can not be null

Error message

baseUrl can not be null

What it means

This FlowableIllegalArgumentException is thrown by taskNameIn(Collection) in HistoricTaskInstanceQueryImpl when a historic task query tries to use taskNameIn together with another name filter that is already set (taskName, taskNameLike, or taskNameLikeIgnoreCase). The query builder allows only one name-matching strategy per query, because the SQL would otherwise be ambiguous or contradictory. It is a fail-fast misuse check, not a runtime failure.

Source

Thrown at modules/flowable-app-engine-rest/src/main/java/org/flowable/app/rest/AppRestUrlBuilder.java:57

    protected AppRestUrlBuilder() {
    }

    protected AppRestUrlBuilder(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public String buildUrl(String[] fragments, Object... arguments) {
        return new StringBuilder(baseUrl).append("/").append(MessageFormat.format(StringUtils.join(fragments, '/'), arguments)).toString();
    }

    /** Uses baseUrl as the base URL */
    public static AppRestUrlBuilder usingBaseUrl(String baseUrl) {
        if (baseUrl == null) {
            throw new FlowableIllegalArgumentException("baseUrl can not be null");
        }
        if (baseUrl.endsWith("/")) {
            baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
        }
        return new AppRestUrlBuilder(baseUrl);
    }

    /** Extracts the base URL from the request */
    public static AppRestUrlBuilder fromRequest(HttpServletRequest request) {
        return usingBaseUrl(ServletUriComponentsBuilder.fromServletMapping(request).build().toUriString());
    }

    /** Extracts the base URL from current request */
    public static AppRestUrlBuilder fromCurrentRequest() {
        return usingBaseUrl(ServletUriComponentsBuilder.fromCurrentServletMapping().build().toUriString());
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Remove the earlier taskName / taskNameLike / taskNameLikeIgnoreCase call so only taskNameIn is set.
  2. If both filters are truly needed, run two queries (one per name criterion) and merge results in application code.
  3. Restructure filter-building code so name criteria are mutually exclusive (e.g., else-if branches, or clear the field before calling taskNameIn).

Example fix

// before
query.taskNameLike("Report%");
query.taskNameIn(List.of("Report A", "Report B")); // throws

// after
query.taskNameIn(List.of("Report A", "Report B"));
Defensive patterns

Strategy: validation

Validate before calling

boolean hasOtherNameFilter = query.getTaskName() != null || query.getTaskNameLike() != null || query.getTaskNameLikeIgnoreCase() != null;
if (hasOtherNameFilter) {
    throw new IllegalStateException("Use taskNameIn OR name filters, not both");
}
query.taskNameIn(names);

Prevention

When it happens

Trigger: Calling historicTaskInstanceQuery.taskNameIn(List.of("a","b")) after having previously called taskName("x"), taskNameLike("x%"), or taskNameLikeIgnoreCase("x%") on the same query object (in either order).

Common situations: Building a query incrementally from optional user filters where both an exact-name list and a name/description search end up set; copying an existing query object and adding taskNameIn without clearing prior name criteria; merging two filter builders into one query.

Related errors


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