flowable/flowable-engine · error · NullPointerException

error.method.notypes

error.method.notypes

Error message

error.method.notypes

What it means

Per the EL specification, constructing a TreeMethodExpression with a non-literal, non-method-invocation left-value expression requires an explicit parameter types array. When paramTypes is null in that case, the constructor throws a NullPointerException with message 'error.method.notypes'.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/TreeMethodExpression.java:95

		this.builder = store.getBuilder();
		this.bindings = tree.bind(functions, variables, converter);
		this.expr = expr;
		this.type = returnType;
		this.types = paramTypes;
		this.node = tree.getRoot();
		this.deferred = tree.isDeferred();

		if (node.isLiteralText()) {
			if (returnType == void.class || returnType == Void.class) {
				throw new ELException(LocalMessages.get("error.method.literal.void", expr));
			}
		} else if (!node.isMethodInvocation()) {
			if (!node.isLeftValue()) {
				throw new ELException(LocalMessages.get("error.method.invalid", expr));
			}
			if (paramTypes == null) {
				throw new NullPointerException(LocalMessages.get("error.method.notypes")); // EL specification requires NPE
			}
		}
	}

	private String getStructuralId() {
		if (structure == null) {
			structure = node.getStructuralId(bindings);
		}
		return structure;
	}
	
  /**
   * Evaluates the expression and answers information about the method
   * @param context used to resolve properties (<code>base.property</code> and <code>base[property]</code>)
   * @return method information or <code>null</code> for literal expressions
   * @throws ELException if evaluation fails (e.g. suitable method not found)
   */
	@Override

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Provide a paramTypes array, e.g. new Class<?>[0] for a no-arg invocation.
  2. Use a genuine method-invocation expression ('#{bean.method()}') so paramTypes is not required.
  3. If a value was intended, switch to TreeValueExpression.

Example fix

// before
new TreeMethodExpression(store, ctx, fns, vars, "#{bean.prop}", null, Object.class)
// after
new TreeMethodExpression(store, ctx, fns, vars, "#{bean.prop}", new Class<?>[0], Object.class)
Defensive patterns

Strategy: validation

Validate before calling

if (paramTypes == null && !expr.contains("(")) {
    paramTypes = new Class<?>[0]; // l-value method expression requires explicit param types
}

Type guard

boolean requiresParamTypes(String expr, Class<?>[] paramTypes) {
    return paramTypes == null && expr.startsWith("#{") && !expr.contains("(");
}

Try / catch

try {
    TreeMethodExpression m = new TreeMethodExpression(store, ctx, fns, vars, expr, paramTypes, returnType);
} catch (NullPointerException e) {
    // paramTypes was null for an l-value expression; supply new Class<?>[0]
}

Prevention

When it happens

Trigger: new TreeMethodExpression(..., expr, null, returnType) where expr is an l-value (e.g. '#{bean.property}') rather than a method invocation.

Common situations: Binding an l-value expression as a method expression (e.g. property getter used as an action) without declaring paramTypes; API misuse where the caller assumed paramTypes is optional.

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