flowable/flowable-engine · error · PropertyNotFoundException

error.property.property.notfound

Error message

error.property.property.notfound

What it means

In strict mode, AstProperty.getValueReference throws PropertyNotFoundException('error.property.property.notfound') when the property part of the expression (e.g. the key or name after the dot/bracket) is null. Strict resolution demands a concrete property; null is not acceptable.

Solutions

  1. Ensure the property/key variable is set and non-null before evaluation, e.g. validate inputs that feed the bracket expression.
  2. Supply a default key: ${map[key != null ? key : 'default']}.
  3. Use non-strict (lenient) resolution if null properties should be tolerated in your setup.
  4. Fix the expression so the property is a literal or always-resolvable expression.

Example fix

// before
${params[field]} // field is null, strict mode
// after
${params[field != null ? field : 'defaultValue']}
Defensive patterns

Strategy: validation

Validate before calling

String key = (String) factory.createValueExpression(ctx, "${field}", String.class).getValue(context);
if (key == null || key.isEmpty()) {
    throw new IllegalStateException("Property key 'field' must be set before strict property access");
}

Type guard

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

Try / catch

try {
    return ve.getValueReference(context);
} catch (PropertyNotFoundException e) {
    if (!e.getMessage().contains("property.notfound")) throw e;
    return null; // tolerate missing dynamic property
}

Prevention

When it happens

Trigger: Dynamic property access ${map[key]} or ${bean[fieldName]} in strict resolver mode where the key expression evaluates to null; malformed expressions where the property token is missing.

Common situations: Dynamic field selection driven by a config/variable that is unset; accessing map entries with keys computed from user input that is empty; strict ELContext (non-lenient) resolving incomplete expressions.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java:61

		this.strict = strict;
		this.ignoreReturnType = ignoreReturnType;
	}

	protected abstract Object getProperty(Bindings bindings, ELContext context) throws ELException;

	protected AstNode getPrefix() {
		return prefix;
	}

	@Override
	public ValueReference getValueReference(Bindings bindings, ELContext context) {
		Object base = prefix.eval(bindings, context);
		if (base == null) {
			throw new PropertyNotFoundException(LocalMessages.get("error.property.base.null", prefix));
		}
		Object property = getProperty(bindings, context);
		if (property == null && strict) {
			throw new PropertyNotFoundException(LocalMessages.get("error.property.property.notfound", "null", base));
		}
		return new ValueReference(base, property);
	}
	
	@Override
	public Object eval(Bindings bindings, ELContext context) {
		Object base = prefix.eval(bindings, context);
		if (base == null) {
			return null;
		}
		Object property = getProperty(bindings, context);
		if (property == null && strict) {
			return null;
		}
		context.setPropertyResolved(false);
		Object result = context.getELResolver().getValue(context, base, property);
		if (!context.isPropertyResolved()) {
			throw new PropertyNotFoundException(LocalMessages.get("error.property.property.notfound", property, base));

View on GitHub (pinned to d6d39ce1c6)