{"record":{"id":"fec0fc2aefe7fa40","repo":"apache/druid","slug":"function-s-s","errorCode":null,"errorMessage":"Function[%s] %s","messagePattern":"Function\\[(.+?)\\] (.+?)","errorType":"validation","errorClass":"ExpressionValidationException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java","lineNumber":46,"sourceCode":" * Common stuff for \"named\" functions of \"functional\" expressions, such as {@link FunctionExpr},\n * {@link ApplyFunctionExpr}, and {@link ExprMacroTable.ExprMacroFunctionExpr}.\n *\n * Provides helper methods for performing common validation operations to help reduce boilerplate for implementors and\n * make it easier to provide consistent error messaging.\n */\npublic interface NamedFunction\n{\n  /**\n   * Name of the function\n   */\n  String name();\n\n  /**\n   * Helper method for creating a {@link ExpressionValidationException} with the specified reason\n   */\n  default ExpressionValidationException validationFailed(String reasonFormat, Object... args)\n  {\n    throw new ExpressionValidationException(this, reasonFormat, args);\n  }\n\n  default ExpressionValidationException validationFailed(Throwable e, String reasonFormat, Object... args)\n  {\n    throw new ExpressionValidationException(this, e, reasonFormat, args);\n  }\n\n  default ExpressionProcessingException processingFailed(String reasonFormat, Object... args)\n  {\n    throw new ExpressionProcessingException(this, reasonFormat, args);\n  }\n\n  default ExpressionProcessingException processingFailed(Throwable e, String reasonFormat, Object... args)\n  {\n    throw new ExpressionProcessingException(this, e, reasonFormat, args);\n  }\n\n  /**","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/NamedFunction.java#L28-L64","documentation":"NamedFunction.validationFailed is the standard helper for a function implementation to report validation failure; it throws ExpressionValidationException prefixed with Function[<name>]. The %s %s message means the second %s carries the function-specific reason (e.g. wrong argument count). Thrown during expression validation (Parser.validateExpr / planning validation) when arguments are invalid.","triggerScenarios":"Calling validationHelperCheckArgumentCount / CheckMinArgumentCount / CheckAnyOfArgumentCount / CheckArgIsLiteral inside a NamedFunction's validation when the supplied args violate the contract — e.g. writing \"abs(a, b)\" (too many args) or passing a non-literal where a literal is required.","commonSituations":"Typo in SQL/native expression function arity; using array functions like array_offset with wrong argument counts; passing a dynamic expression where a constant is mandated; custom extension functions with stricter validation after a Druid upgrade.","solutions":["Read the reason after 'Function[name]' and correct the expression arguments (count/order/literal-ness).","Check the function's documentation for its exact required signature.","If authoring a function, ensure validation helpers are called with the right expected counts in validate()."],"exampleFix":"// before\nExpr e = Parser.parse(\"abs(x, 2)\", null); // Function[abs] requires 1 argument\n// after\nExpr e = Parser.parse(\"abs(x)\", null);","handlingStrategy":"try-catch","validationCode":"// check arity before parsing/validating\nif (args.size() != expectedCount) throw new IllegalArgumentException(\"fn expects \" + expectedCount + \" args\");","typeGuard":null,"tryCatchPattern":"try { Parser.validateExpr(expr, analysis); } catch (ExpressionValidationException e) { log.error(\"{}: {}\", e.getFunctionName(), e.getMessage()); }","preventionTips":["Consult the function docs for exact arity before writing expressions","Validate expressions in CI with Parser.parse/validateExpr","Watch for arity changes across Druid upgrades in custom functions"],"tags":["expression","function-validation","argument-count","druid"],"backgroundTag":"missing-required-argument","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"}