flowable/flowable-engine · error · FlowableException

Initiator header '${processInitiatorHeaderName}': Value must

Error message

Initiator header '${processInitiatorHeaderName}': Value must be provided

What it means

ExchangeUtils.prepareInitiator reads the process initiator header from a Camel exchange when handing the exchange to a Flowable process. Flowable throws this FlowableException when the configured initiator header name is present but its value is empty/null (StringUtils.isEmpty). It guarantees the process variable 'initiator' is a non-empty string.

Source

Thrown at modules/flowable-camel/src/main/java/org/flowable/camel/ExchangeUtils.java:155

     * Gets the value of the Camel header that contains the userId to be set as the process initiator. Returns null if no header name was specified on the Camel route.
     *
     * @param exchange The Camel Exchange object
     * @param endpoint The endPoint implementation
     * @return The userId of the user to be set as the process initiator
     */
    public static String prepareInitiator(Exchange exchange, FlowableEndpoint endpoint) {

        String initiator = null;
        if (endpoint.isSetProcessInitiator()) {
            try {
                initiator = exchange.getIn().getHeader(endpoint.getProcessInitiatorHeaderName(), String.class);
            } catch (TypeConversionException e) {
                throw new FlowableException("Initiator header '" +
                        endpoint.getProcessInitiatorHeaderName() + "': Value must be of type String.", e);
            }

            if (StringUtils.isEmpty(initiator)) {
                throw new FlowableException("Initiator header '" +
                        endpoint.getProcessInitiatorHeaderName() + "': Value must be provided");
            }
        }
        return initiator;
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Populate the initiator header with a non-empty String on the exchange before invoking the Flowable endpoint: exchange.getIn().setHeader(endpoint.getProcessInitiatorHeaderName(), "kermit").
  2. Verify the configured processInitiatorHeaderName on the FlowableEndpoint matches the header actually set.
  3. Validate the value upstream (e.g. reject requests without an authenticated user) before routing to the Flowable endpoint.
  4. If no initiator is intended, remove the header entirely so the initiator block is skipped rather than passing an empty value.

Example fix

// before
exchange.getIn().setHeader("ProcessInitiator", someNullableUserId);
// after
if (userId != null && !userId.trim().isEmpty()) {
    exchange.getIn().setHeader("ProcessInitiator", userId);
}
Defensive patterns

Strategy: validation

Validate before calling

String initiator = exchange.getIn().getHeader(endpoint.getProcessInitiatorHeaderName(), String.class);
if (initiator == null || initiator.trim().isEmpty()) {
    throw new IllegalArgumentException("Initiator header '" + endpoint.getProcessInitiatorHeaderName() + "' must be a non-empty String");
}

Prevention

When it happens

Trigger: Calling a Flowable camel endpoint with the initiator header set (e.g. ExchangeUtils.prepareInitiator invoked from FlowableConsumer/process) but the header value is null, an empty string, or whitespace. Distinct from the type-conversion error: here the value was either not convertible or simply absent after the header name resolved.

Common situations: Setting the header from a dynamic expression that evaluates to null; copying headers from an incoming HTTP request where the user-identity header was omitted; typos causing a different header to be read than the one populated; passing an empty String literal.

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/91b1f916927ad34a. Report an issue: GitHub.