flowable/flowable-engine · warning

Case should be validated, but no case validator is…

Error message

Case should be validated, but no case validator is configured on the case engine configuration!

What it means

CmmnParserImpl.validateCmmnModel runs the configured CaseValidator against the parsed CmmnModel before deployment. If engine configuration has validation enabled (or is expected to validate) but caseValidator is null, the parser logs this warning and skips validation entirely, so an invalid case model can be deployed. Flowable logs it because deploying unvalidated models usually surfaces errors later at runtime.

Solutions

  1. Ensure the engine configuration creates/sets a validator: cmmnEngineConfiguration.setCaseValidatorFactory(new CmmnCaseValidatorFactory()) or use the standard FlowableCmmnEngineConfiguration which wires it by default
  2. Explicitly set caseValidator on the configuration before deploying if constructing CmmnParserImpl manually
  3. If validation is intentionally skipped, silence is expected but consider running a manual validation pass on models before deploy
  4. Verify the Spring/spring-boot starter auto-configuration is in play so the default validator bean is registered

Example fix

// before: validator never configured
FlowableCmmnEngineConfiguration config = new FlowableCmmnEngineConfiguration();
// after: ensure validator is configured
config.setCaseValidatorFactory(new CmmnCaseValidatorFactory());
Defensive patterns

Strategy: validation

Validate before calling

if (cmmnEngineConfiguration.getCaseValidator() == null) {
    throw new IllegalStateException("CaseValidator must be configured before deploying CMMN models");
}

Prevention

When it happens

Trigger: Calling CmmnParserImpl.parse when the CaseValidator injected via the engine configuration (e.g. CmmnEngineConfiguration's caseValidator field) is null — typically because the validator was never set on the configuration, or a custom configuration replaced the default CaseValidatorFactory output with null.

Common situations: Building a CmmnEngineConfiguration programmatically without setting the case validator; using a stripped-down/custom configuration class that omits CaseValidatorFactory; upgrading Flowable and a custom config no longer wires the validator.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/parser/CmmnParserImpl.java:90

            } else if (e instanceof CmmnXMLException) {
                throw (CmmnXMLException) e;
            } else {
                throw new FlowableException("Error parsing XML", e);
            }
        }
    }

    protected CmmnModel convertToCmmnModel(CmmnParseContext context, StreamSource cmmnSource) {
        boolean enableSafeBpmnXml = context.enableSafeXml();
        String encoding = context.xmlEncoding();
        boolean validateCmmnXml = context.validateXml();

        return new CmmnXmlConverter().convertToCmmnModel(cmmnSource, validateCmmnXml, enableSafeBpmnXml, encoding);
    }

    protected void validateCmmnModel(CaseValidator caseValidator, CmmnModel cmmnModel) {
        if (caseValidator == null) {
            logger.warn("Case should be validated, but no case validator is configured on the case engine configuration!");
        } else {
            List<ValidationEntry> validationEntries = caseValidator.validate(cmmnModel);
            if (validationEntries != null && !validationEntries.isEmpty()) {

                StringBuilder warningBuilder = new StringBuilder();
                StringBuilder errorBuilder = new StringBuilder();

                for (ValidationEntry entry : validationEntries) {
                    if (entry.getLevel() == ValidationEntry.Level.Warning) {
                        warningBuilder.append(entry).append("\n");
                    } else {
                        errorBuilder.append(entry).append("\n");
                    }
                }

                // Throw exception if there is any error
                if (errorBuilder.length() > 0) {
                    throw new FlowableException("Errors while parsing:\n" + errorBuilder);

View on GitHub (pinned to d6d39ce1c6)