flowable/flowable-engine · error · ActivitiIllegalArgumentException

Error Code must not be empty.

Error message

Error Code must not be empty.

What it means

Besides being non-null, a BpmnError errorCode must have length >= 1. setErrorCode() throws ActivitiIllegalArgumentException("Error Code must not be empty.") when an empty string is supplied, because an empty code can never be matched by any error boundary event definition.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/delegate/BpmnError.java:52

    private String errorCode;

    public BpmnError(String errorCode) {
        super("");
        setErrorCode(errorCode);
    }

    public BpmnError(String errorCode, String message) {
        super(message + " (errorCode='" + errorCode + "')");
        setErrorCode(errorCode);
    }

    protected void setErrorCode(String errorCode) {
        if (errorCode == null) {
            throw new ActivitiIllegalArgumentException("Error Code must not be null.");
        }
        if (errorCode.length() < 1) {
            throw new ActivitiIllegalArgumentException("Error Code must not be empty.");
        }
        this.errorCode = errorCode;
    }

    public String getErrorCode() {
        return errorCode;
    }

    @Override
    public String toString() {
        return super.toString() + " (errorCode='" + errorCode + "')";
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Provide a real non-empty error code matching the errorCode attribute of the boundary/error start event in the BPMN XML.
  2. Trim and check before throwing: if (code == null || code.trim().isEmpty()) code = fallback.
  3. Fix the upstream data source producing the empty string.

Example fix

// before
throw new BpmnError(errorCode); // errorCode == ""
// after
if (errorCode == null || errorCode.trim().isEmpty()) {
    errorCode = "UNSPECIFIED_ERROR";
}
throw new BpmnError(errorCode);
Defensive patterns

Strategy: validation

Validate before calling

if (errorCode == null || errorCode.trim().isEmpty()) errorCode = "UNSPECIFIED_ERROR";

Type guard

boolean isNonEmpty(String s) { return s != null && !s.trim().isEmpty(); }

Try / catch

try { serviceCall(); } catch (ActivitiIllegalArgumentException e) { if (e.getMessage().contains("must not be empty")) { throw new BpmnError("FALLBACK_CODE"); } throw e; }

Prevention

When it happens

Trigger: new BpmnError("") or new BpmnError(message, "") — constructors receiving an empty-string error code.

Common situations: Error code read from a config file / process variable / DB column that is empty string rather than null; string building that produced "" (e.g. split or substring yielding empty).

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