{"record":{"id":"2b532b6b8949379a","repo":"apache/druid","slug":"second-argument-should-be-string-but-got-s-instea","errorCode":null,"errorMessage":"second argument should be STRING but got %s instead","messagePattern":"second argument should be STRING but got (.+?) instead","errorType":"validation","errorClass":"ExpressionValidationException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Function.java","lineNumber":3209,"sourceCode":"    @Override\n    public String name()\n    {\n      return \"timestamp\";\n    }\n\n    @Override\n    public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)\n    {\n      ExprEval value = args.get(0).eval(bindings);\n      if (value.value() == null) {\n        return ExprEval.ofLong(null);\n      }\n\n      DateTimes.UtcFormatter formatter = DateTimes.ISO_DATE_OPTIONAL_TIME;\n      if (args.size() > 1) {\n        ExprEval format = args.get(1).eval(bindings);\n        if (!format.type().is(ExprType.STRING)) {\n          throw validationFailed(\n              \"second argument should be STRING but got %s instead\",\n              format.type()\n          );\n        }\n        formatter = DateTimes.wrapFormatter(DateTimeFormat.forPattern(format.asString()));\n      }\n      DateTime date;\n      try {\n        date = formatter.parse(value.asString());\n      }\n      catch (IllegalArgumentException e) {\n        throw validationFailed(e, \"invalid value %s\", value.asString());\n      }\n      return toValue(date);\n    }\n\n    @Override\n    public void validateArguments(List<Expr> args)","sourceCodeStart":3191,"sourceCodeEnd":3227,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Function.java#L3191-L3227","documentation":"Thrown by Druid's time-formatting expression function when its optional second argument (the date format pattern) is not a STRING. The function builds a Joda-Time DateTimeFormat pattern from that argument, so a non-string type (LONG, DOUBLE, array, etc.) cannot be used and the expression is rejected at evaluation/validation time with a validation failure.","triggerScenarios":"Calling the time format function with a second argument that evaluates to a non-STRING ExprType, e.g. time_format(ts, 1234) or passing a numeric column/literal instead of a quoted pattern like 'yyyy-MM-dd'.","commonSituations":"Copy-pasted SQL where the pattern string lost its quotes; passing a numeric format constant or a JSON object; translating queries from other engines where formats are numbers (e.g. strftime-style enums); typed columns in inputs that were inferred as LONG.","solutions":["Quote the format pattern as a string literal, e.g. time_format(ts, 'yyyy-MM-dd HH:mm:ss').","Cast or convert the second argument to a string with CAST(... AS VARCHAR) / CONCAT before passing it.","Check the argument type with the EXTRACT_TYPE or a query plan to confirm what type the expression yields.","If the pattern is optional, remove the second argument entirely to use the default ISO_DATE_OPTIONAL_TIME formatter."],"exampleFix":"// before\ntime_format(__time, yyyy-MM-dd)\n// after\ntime_format(__time, 'yyyy-MM-dd')","handlingStrategy":"validation","validationCode":"// Java caller-side check before building the expression\nif (!(formatArg instanceof String)) {\n    throw new IllegalArgumentException(\"time_format second argument must be a string pattern\");\n}","typeGuard":"// SQL: enforce via CAST\nCAST(pattern_expr AS VARCHAR)","tryCatchPattern":"// wrap query submission; Druid surfaces this as an expression validation error\ntry { runQuery(q); } catch (ExpressionValidationException e) { /* fix format arg type */ }","preventionTips":["Always quote date format patterns as string literals","Dry-run/EXPLAIN queries before execution","Keep format patterns in constants, not computed values"],"tags":["druid","expressions","type-mismatch","datetime"],"backgroundTag":"type-mismatch","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}