flowable/flowable-engine · error · IllegalStateException

The [ ] must resolve to a Boolean or a String that can be…

Error message

The [<attribute>] must resolve to a Boolean or a String that can be parsed as a Boolean. Resolved to [<class>] for [<value>]

What it means

resolveExpressionAsBoolean resolves a channel-model attribute to Boolean and accepts Boolean, Boolean.parseBoolean-able String, or null; any other resolved type throws IllegalStateException with the attribute name, class, and raw value. Used for flags in resolveRetryConfiguration and recursive calls.

Solutions

  1. Use true/false or "true"/"false" values for the attribute.
  2. Change the backing property/env var to a boolean (AUTO_CREATE=true instead of 1).
  3. Fix the expression to return Boolean, e.g. ${flag} != 0 style conversion.
  4. Verify no custom property resolver returns boxed numbers for boolean keys.

Example fix

// before
auto-create-topics: ${KAFKA_AUTO_CREATE}   # env var is "1"

// after
auto-create-topics: ${KAFKA_AUTO_CREATE:false}  # and set KAFKA_AUTO_CREATE=true
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = resolveExpression(value);
if (v != null && !(v instanceof Boolean) && !(v instanceof String)) throw new IllegalArgumentException(attribute + " must be boolean-like");

Type guard

boolean isBooleanLike(Object v) { return v == null || v instanceof Boolean || v instanceof String; }

Try / catch

try { ... } catch (IllegalStateException e) { if (e.getMessage().contains("parsed as a Boolean")) { log.error("Flag attribute wrong type: {}", e.getMessage()); } else throw e; }

Prevention

When it happens

Trigger: A boolean channel attribute (e.g. autoCreateTopics, autoStartup) is expressed as an expression resolving to a non-Boolean object such as Integer or Map when the Kafka listener endpoint is configured.

Common situations: YAML value like autoCreateTopics: 1 (Integer) via placeholder resolution; expression returning Optional or custom wrapper; property pointing to a numeric env var (AUTO_CREATE=1).

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/kafka/KafkaChannelDefinitionProcessor.java:511

                    "The [" + attribute + "] must resolve to an Number or a String that can be parsed as a Double. "
                            + "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
        }
        return result;
    }

    protected Boolean resolveExpressionAsBoolean(String value, String attribute) {
        return resolveExpressionAsBoolean(value, attribute, null);
    }

    protected Boolean resolveExpressionAsBoolean(String value, String attribute, Boolean defaultValue) {
        Object resolved = resolveExpression(value);
        Boolean result = defaultValue;
        if (resolved instanceof String) {
            result = Boolean.parseBoolean((String) resolved);
        } else if (resolved instanceof Boolean) {
            result = (Boolean) resolved;
        } else if (resolved != null) {
            throw new IllegalStateException(
                    "The [" + attribute + "] must resolve to a Boolean or a String that can be parsed as a Boolean. "
                            + "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
        }
        return result;
    }

    protected String resolveExpressionAsString(String value, String attribute) {
        if (!StringUtils.hasLength(value)) {
            return null;
        }
        Object resolved = resolveExpression(value);
        if (resolved instanceof String) {
            return (String) resolved;
        } else {
            throw new IllegalStateException("The [" + attribute + "] must resolve to a String. "
                + "Resolved to [" + resolved.getClass() + "] for [" + value + "]");
        }
    }

View on GitHub (pinned to d6d39ce1c6)