flowable/flowable-engine · error · FlowableException

The channel expression key detection value was not found for

Error message

The channel expression key detection value was not found for the channel model with key ${channelModel.key}. One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.

What it means

When a channel model declares a ChannelEventKeyDetection but none of its detection properties (fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression) is set, no InboundEventKeyDetector can be constructed. Flowable throws this error during createExpressionEventProcessingPipeline. It is a validation that exactly one usable key detection strategy is configured.

Source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/pipeline/InboundChannelModelProcessor.java:343

        InboundEventKeyDetector<?> eventKeyDetector;
        ChannelEventKeyDetection keyDetection = channelModel.getChannelEventKeyDetection();

        if (keyDetection == null) {
            throw new FlowableException("A channel key detection value is required for inbound channel " + channelModel.getKey());
        }

        if (StringUtils.isNotEmpty(keyDetection.getDelegateExpression())) {
            eventKeyDetector = resolveExpression(keyDetection.getDelegateExpression(), InboundEventKeyDetector.class);
        } else if (StringUtils.isNotEmpty(keyDetection.getFixedValue())) {
            eventKeyDetector = new InboundEventStaticKeyDetector<>(keyDetection.getFixedValue());
        } else if (StringUtils.isNotEmpty(keyDetection.getJsonField())) {
            eventKeyDetector = new JsonFieldBasedInboundEventKeyDetector(keyDetection.getJsonField());
        } else if (StringUtils.isNotEmpty(keyDetection.getJsonPointerExpression())) {
            eventKeyDetector = new JsonPointerBasedInboundEventKeyDetector(keyDetection.getJsonPointerExpression(), objectMapper);
        } else if (StringUtils.isNotEmpty(keyDetection.getXmlXPathExpression())) {
            eventKeyDetector = new XpathBasedInboundEventKeyDetector(keyDetection.getXmlXPathExpression());
        } else {
            throw new FlowableException(
                "The channel expression key detection value was not found for the channel model with key " + channelModel.getKey()
                    + ". One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.");
        }

        ChannelEventTenantIdDetection channelEventTenantIdDetection = channelModel.getChannelEventTenantIdDetection();
        if (channelEventTenantIdDetection != null) {
            if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getDelegateExpression())) {
                eventTenantDetector = resolveExpression(channelEventTenantIdDetection.getDelegateExpression(), InboundEventTenantDetector.class);
            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getFixedValue())) {
                eventTenantDetector = new InboundEventStaticTenantDetector<>(channelEventTenantIdDetection.getFixedValue());
            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getJsonPointerExpression())) {
                eventTenantDetector = new JsonPointerBasedInboundEventTenantDetector(channelEventTenantIdDetection.getJsonPointerExpression());
            } else if (StringUtils.isNotEmpty(channelEventTenantIdDetection.getxPathExpression())) {
                eventTenantDetector = new XpathBasedInboundEventTenantDetector(channelEventTenantIdDetection.getxPathExpression());
            } else {
                throw new FlowableException(
                    "The channel expression tenant detection value was not found for the channel model with key " + channelModel.getKey()
                        + ". One of fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, delegateExpression should be set.");

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Set one of the supported detection values on the channel model: fixedValue, jsonField, jsonPointerExpression, xmlXPathExpression, or delegateExpression (e.g. keyDetectionJsonField("type"))
  2. Verify the serialized channel model resource actually contains the chosen value (e.g. <channelEventKeyDetection fixedValue="orderEvent"/>) and redeploy
  3. If detection logic is complex, implement an InboundEventKeyDetector bean and reference it with keyDetectionDelegateExpression("${myKeyDetector}")

Example fix

// before
ChannelEventKeyDetection detection = new ChannelEventKeyDetection();
channelModel.setChannelEventKeyDetection(detection); // empty
// after
ChannelEventKeyDetection detection = new ChannelEventKeyDetection();
detection.setJsonField("eventType");
channelModel.setChannelEventKeyDetection(detection);
Defensive patterns

Strategy: validation

Validate before calling

ChannelEventKeyDetection d = channelModel.getChannelEventKeyDetection();
if (d == null || (isEmpty(d.getFixedValue()) && isEmpty(d.getJsonField()) && isEmpty(d.getJsonPointerExpression()) && isEmpty(d.getXmlXPathExpression()) && isEmpty(d.getDelegateExpression()))) {
    throw new IllegalArgumentException("Channel '" + channelModel.getKey() + "' key detection has no detection value set");
}

Try / catch

try {
    eventRepositoryService.registerChannelModel(...);
} catch (FlowableException e) {
    if (e.getMessage().contains("expression key detection value was not found")) {
        // fix channel model keyDetection config and redeploy
    } else { throw e; }
}

Prevention

When it happens

Trigger: registerChannelModel on an inbound channel whose ChannelEventKeyDetection object exists but has all detection fields empty/null, so the if/else-if chain in createExpressionEventProcessingPipeline falls through to the else throw.

Common situations: Creating a keyDetection element in the channel model XML but leaving it empty; calling keyDetection() builder method without a value; serializing/deserializing the model and dropping field values; typos in the XML attribute name so the value lands on an unrecognized property.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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