{"record":{"id":"590ad3eebb4d2fc5","repo":"flowable/flowable-engine","slug":"function-has-more-than-one-local-name","errorCode":null,"errorMessage":"Function has more than one local name","messagePattern":"Function has more than one local name","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common-api/src/main/java/org/flowable/common/engine/api/delegate/FlowableMultiFunctionDelegate.java","lineNumber":25,"sourceCode":" * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.flowable.common.engine.api.delegate;\n\nimport java.lang.reflect.Method;\nimport java.util.Collection;\n\n/**\n * @author Filip Hrisafov\n */\npublic interface FlowableMultiFunctionDelegate extends FlowableFunctionDelegate {\n\n    @Override\n    default String localName() {\n        throw new UnsupportedOperationException(\"Function has more than one local name\");\n    }\n\n    @Override\n    Collection<String> localNames();\n\n    @Override\n    default Method functionMethod() {\n        throw new UnsupportedOperationException(\"Function Delegate has more than one function method\");\n    }\n\n    @Override\n    Method functionMethod(String prefix, String localName) throws  NoSuchMethodException;\n}\n","sourceCodeStart":7,"sourceCodeEnd":39,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common-api/src/main/java/org/flowable/common/engine/api/delegate/FlowableMultiFunctionDelegate.java#L7-L39","documentation":"FlowableMultiFunctionDelegate.localName() is a default interface method that deliberately throws UnsupportedOperationException(\"Function has more than one local name\") because a multi-function delegate supports several local names instead of exactly one. Implementations must override localNames() and functionMethod(String,String) instead.","triggerScenarios":"Calling localName() directly on a FlowableMultiFunctionDelegate, or engine/function-lookup code that assumes single-name FlowableFunctionDelegate semantics and queries localName() on a multi-name function.","commonSituations":"Custom JUEL/flowable function registrars iterating all function delegates and calling localName() uniformly without an instanceof FlowableMultiFunctionDelegate check.","solutions":["Use localNames() (the Collection) instead of localName() when working with multi-function delegates","Add an instanceof FlowableMultiFunctionDelegate check and branch to localNames() / functionMethod(prefix, localName)","If this delegate should have a single name, implement FlowableFunctionDelegate directly with localName() and functionMethod()"],"exampleFix":"// before\nString name = delegate.localName();\n// after\nString name = delegate instanceof FlowableMultiFunctionDelegate\n        ? ((FlowableMultiFunctionDelegate) delegate).localNames().iterator().next()\n        : delegate.localName();","handlingStrategy":"type-guard","validationCode":"// avoid calling localName() on multi-function delegates\nif (delegate instanceof FlowableMultiFunctionDelegate) {\n    List<String> names = new ArrayList<>(((FlowableMultiFunctionDelegate) delegate).localNames());\n} else {\n    String name = delegate.localName();\n}","typeGuard":"static boolean isMultiFunction(FlowableFunctionDelegate d) {\n    return d instanceof FlowableMultiFunctionDelegate;\n}","tryCatchPattern":"try {\n    String name = delegate.localName();\n} catch (UnsupportedOperationException e) {\n    Collection<String> names = ((FlowableMultiFunctionDelegate) delegate).localNames();\n}","preventionTips":["Treat FlowableMultiFunctionDelegate as a distinct API surface (localNames/functionMethod(prefix, localName))","Add instanceof checks in generic function-registry code","Read the interface contract before implementing or consuming function delegates","Unit-test custom function registration with both delegate kinds"],"tags":["java","unsupported-operation","api-misuse"],"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"}