{"record":{"id":"80f9a113d78222d9","repo":"flowable/flowable-engine","slug":"function-has-more-than-one-prefix","errorCode":null,"errorMessage":"Function has more than one prefix","messagePattern":"Function has more than one prefix","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/function/AbstractFlowableVariableExpressionFunction.java","lineNumber":72,"sourceCode":"    public AbstractFlowableVariableExpressionFunction(List<String> functionNameOptions, String functionName) {\n        this.functionNamesOptions = new LinkedHashSet<>(functionNameOptions);\n        this.functionName = functionName;\n\n    }\n\n    protected Method findMethod(String functionName) {\n        Method[] methods = this.getClass().getMethods();\n        for (Method method : methods) {\n            if (Modifier.isStatic(method.getModifiers()) && method.getName().equals(functionName)) {\n                return method;\n            }\n        }\n        throw new FlowableException(\"Programmatic error: could not find method \" + functionName + \" on class \" + this.getClass());\n    }\n\n    @Override\n    public String prefix() {\n        throw new UnsupportedOperationException(\"Function has more than one prefix\");\n    }\n\n    @Override\n    public Collection<String> prefixes() {\n        return FUNCTION_PREFIXES;\n    }\n\n    @Override\n    public String localName() {\n        throw new UnsupportedOperationException(\"Function has more than one local name\");\n    }\n\n    @Override\n    public Collection<String> localNames() {\n        return functionNamesOptions;\n    }\n\n    @Override","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/el/function/AbstractFlowableVariableExpressionFunction.java#L54-L90","documentation":"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.","triggerScenarios":"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().","commonSituations":"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().","solutions":["Call prefixes() and iterate over the collection instead of prefix().","If a single prefix is required, construct the function with exactly one prefix so prefix() is usable.","Update custom introspection/registration code to handle multi-prefix functions."],"exampleFix":"// before\nString p = function.prefix();\n\n// after\nfor (String p : function.prefixes()) { register(p, function.localNames(), ...); }","handlingStrategy":"type-guard","validationCode":"if (function.prefixes().size() != 1) {\n    // must use prefixes()\n}","typeGuard":"String safePrefix(AbstractFlowableVariableExpressionFunction f) {\n    return f.prefixes().size() == 1 ? f.prefixes().iterator().next() : null;\n}","tryCatchPattern":"try {\n    String p = function.prefix();\n} catch (UnsupportedOperationException e) {\n    // multi-prefix function: iterate function.prefixes() instead\n}","preventionTips":["Always use prefixes() for generic code handling Flowable EL functions.","Only call prefix() when you constructed the function with a single prefix.","Test custom introspection code against the default multi-prefix functions (vars:*, variables:*)."],"tags":["el","function","api-usage"],"backgroundTag":"unsupported-operation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}