{"record":{"id":"b5ce953a72ef21bb","repo":"apache/druid","slug":"unable-to-transform-apply-function-s","errorCode":null,"errorMessage":"Unable to transform apply function:[%s]","messagePattern":"Unable to transform apply function:\\[(.+?)\\]","errorType":"exception","errorClass":"RE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Parser.java","lineNumber":612,"sourceCode":"            new ArrayList<>(expr.lambdaExpr.getIdentifiers().size() + unappliedLambdaBindings.size());\n        final List<IdentifierExpr> existingFoldLambdaIdentifiers = expr.lambdaExpr.getIdentifierExprs();\n        // accumulator argument is last argument, slice it off when constructing new arg list and lambda args\n        for (int i = 0; i < expr.argsExpr.size() - 1; i++) {\n          newFoldArgs.add(expr.argsExpr.get(i));\n          newFoldLambdaIdentifiers.add(existingFoldLambdaIdentifiers.get(i));\n        }\n        newFoldArgs.addAll(unappliedLambdaBindings);\n        newFoldLambdaIdentifiers.addAll(unappliedLambdaBindings);\n        // add accumulator last\n        newFoldLambdaIdentifiers.add(existingFoldLambdaIdentifiers.get(existingFoldLambdaIdentifiers.size() - 1));\n        newFoldArgs.add(expr.argsExpr.get(expr.argsExpr.size() - 1));\n        final LambdaExpr newFoldLambda = new LambdaExpr(newFoldLambdaIdentifiers, expr.lambdaExpr.getExpr());\n\n        newFn = new ApplyFunction.CartesianFoldFunction();\n        newExpr = new ApplyFunctionExpr(newFn, newFn.name(), newFoldLambda, newFoldArgs);\n        break;\n      default:\n        throw new RE(\"Unable to transform apply function:[%s]\", expr.function.name());\n    }\n\n    return newExpr;\n  }\n\n  /**\n   * Validate that an expression uses input bindings in a type consistent manner.\n   */\n  public static void validateExpr(Expr expression, Expr.BindingAnalysis bindingAnalysis)\n  {\n    final Set<String> conflicted =\n        Sets.intersection(bindingAnalysis.getScalarBindings(), bindingAnalysis.getArrayBindings());\n    if (!conflicted.isEmpty()) {\n      throw new RE(\"Invalid expression: %s; %s used as both scalar and array variables\", expression, conflicted);\n    }\n  }\n\n}","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Parser.java#L594-L630","documentation":"During unapply/lifting of lambda-apply expressions (rewriteUnappliedSubExpressions → liftApplyLambda), Parser only knows how to transform specific apply functions (e.g. CartesianFoldFunction). Reaching the default branch means an ApplyFunctionExpr uses an apply function the lift transformation does not support, so RE 'Unable to transform apply function:[%s]' is thrown.","triggerScenarios":"Expression flattening/rewrite (Parser with flatten=true or rewriteUnappliedSubExpressions) encountering apply-lambda expressions using fold variants other than the handled ones — typically with custom or newer ApplyFunction implementations.","commonSituations":"Using lambda expressions (fold/map-style apply) in contexts that trigger the rewriting pass (e.g. expressions requiring flattening); custom extensions adding new ApplyFunction types not registered in the lift logic; Druid version mismatches where a newer function hits older rewrite code.","solutions":["Rewrite the expression to avoid the unsupported apply function, or pre-flatten it manually.","Upgrade Druid so the rewrite logic supports the apply function used.","If extending the engine, add a case for the new ApplyFunction in liftApplyLambda."],"exampleFix":"// before\nExpr e = Parser.parse(\"fold((x) -> x + 1, arr, custom_apply_fn)\", null, true /* flatten */);\n// after — use a supported fold form or flatten=false\nExpr e = Parser.parse(\"map((x) -> x + 1, arr)\", null);","handlingStrategy":"fallback","validationCode":"// avoid flattening expressions containing unsupported apply functions\nboolean hasApply = exprString.contains(\"fold(\") || exprString.contains(\"map(\");","typeGuard":null,"tryCatchPattern":"try { e = Parser.parse(in, macroTable, true); } catch (RuntimeException re) { if (re.getMessage().contains(\"Unable to transform apply function\")) { e = Parser.parse(in, macroTable, false); } }","preventionTips":["Use only built-in apply/fold functions in flattened expressions","Keep Druid versions aligned with expression features you use","Prefer map/filter/reduce built-ins over custom apply implementations"],"tags":["expression","lambda","rewrite","druid"],"backgroundTag":"operation-not-supported","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}