flowable/flowable-engine · error · UnsupportedOperationException

Function has more than one prefix

Error message

Function has more than one prefix

What it means

AbstractFlowableVariableExpressionFunction can be registered under multiple prefixes (e.g. 'flowable' and 'var'). The single prefix() method is only valid when exactly one prefix exists; when the function supports the multiple FUNCTION_PREFIXES, calling prefix() deliberately throws UnsupportedOperationException. Callers must use prefixes() (plural) instead.

Solutions

  1. Call prefixes() and iterate over the collection instead of prefix().
  2. If a single prefix is required, construct the function with exactly one prefix so prefix() is usable.
  3. Update custom introspection/registration code to handle multi-prefix functions.

Example fix

// before
String p = function.prefix();

// after
for (String p : function.prefixes()) { register(p, function.localNames(), ...); }
Defensive patterns

Strategy: type-guard

Validate before calling

if (function.prefixes().size() != 1) {
    // must use prefixes()
}

Type guard

String safePrefix(AbstractFlowableVariableExpressionFunction f) {
    return f.prefixes().size() == 1 ? f.prefixes().iterator().next() : null;
}

Try / catch

try {
    String p = function.prefix();
} catch (UnsupportedOperationException e) {
    // multi-prefix function: iterate function.prefixes() instead
}

Prevention

When it happens

Trigger: Calling prefix() on a function instance constructed with multiple prefixes (the default FUNCTION_PREFIXES behavior); generic EL/JUEL infrastructure code that assumes a single prefix and queries prefix() instead of iterating prefixes().

Common situations: Custom code or a custom EL resolver introspecting Flowable function classes and calling the singular prefix() accessor; implementing a subclass that switches to multiple prefixes but whose consumer still calls prefix().

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/function/AbstractFlowableVariableExpressionFunction.java:72

    public AbstractFlowableVariableExpressionFunction(List<String> functionNameOptions, String functionName) {
        this.functionNamesOptions = new LinkedHashSet<>(functionNameOptions);
        this.functionName = functionName;

    }

    protected Method findMethod(String functionName) {
        Method[] methods = this.getClass().getMethods();
        for (Method method : methods) {
            if (Modifier.isStatic(method.getModifiers()) && method.getName().equals(functionName)) {
                return method;
            }
        }
        throw new FlowableException("Programmatic error: could not find method " + functionName + " on class " + this.getClass());
    }

    @Override
    public String prefix() {
        throw new UnsupportedOperationException("Function has more than one prefix");
    }

    @Override
    public Collection<String> prefixes() {
        return FUNCTION_PREFIXES;
    }

    @Override
    public String localName() {
        throw new UnsupportedOperationException("Function has more than one local name");
    }

    @Override
    public Collection<String> localNames() {
        return functionNamesOptions;
    }

    @Override

View on GitHub (pinned to d6d39ce1c6)