{"record":{"id":"8be329f4f07a283d","repo":"apache/druid","slug":"failed-to-parse-array-element-s-as-a-string","errorCode":null,"errorMessage":"Failed to parse array element %s as a string","messagePattern":"Failed to parse array element (.+?) as a string","errorType":"validation","errorClass":"RE","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/ExprListenerImpl.java","lineNumber":511,"sourceCode":"    }\n    nodes.put(ctx, new ArrayExpr(ExpressionType.STRING_ARRAY, values));\n  }\n\n  @Override\n  public void exitExplicitStringArray(ExprParser.ExplicitStringArrayContext ctx)\n  {\n    Object[] values = new Object[ctx.literalElement().size()];\n    for (int i = 0; i < values.length; i++) {\n      if (ctx.literalElement(i).NULL() != null) {\n        values[i] = null;\n      } else if (ctx.literalElement(i).STRING() != null) {\n        values[i] = escapeStringLiteral(ctx.literalElement(i).STRING().getText());\n      } else if (ctx.literalElement(i).DOUBLE() != null) {\n        values[i] = ctx.literalElement(i).DOUBLE().getText();\n      } else if (ctx.literalElement(i).LONG() != null) {\n        values[i] = ctx.literalElement(i).LONG().getText();\n      } else {\n        throw new RE(\"Failed to parse array element %s as a string\", ctx.literalElement(i).getText());\n      }\n    }\n    nodes.put(ctx, new ArrayExpr(ExpressionType.STRING_ARRAY, values));\n  }\n\n  /**\n   * All {@link IdentifierExpr} that are *not* bound to a {@link LambdaExpr} identifier, will recieve a unique\n   * {@link IdentifierExpr#identifier} value which may or may not be the same as the\n   * {@link IdentifierExpr#binding} value. {@link LambdaExpr} identifiers however, will always have\n   * {@link IdentifierExpr#identifier} be the same as {@link IdentifierExpr#binding} because they have\n   * synthetic bindings set at evaluation time. This is done to aid in analysis needed for the automatic expression\n   * translation which maps scalar expressions to multi-value inputs. See\n   * {@link Parser#applyUnappliedBindings(Expr, Expr.BindingAnalysis, List)}} for additional details.\n   */\n  private IdentifierExpr createIdentifierExpr(String binding)\n  {\n    if (!lambdaIdentifiers.contains(binding)) {\n      String uniqueIdentifier = binding;","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/ExprListenerImpl.java#L493-L529","documentation":"Thrown while parsing an explicit ARRAY<STRING> literal when an element is not NULL, STRING, DOUBLE, or LONG — i.e. a bare identifier or other token cannot be treated as a string element. Unlike the typed-string-array path, numbers are coerced to their text, but non-literals are rejected.","triggerScenarios":"Parsing ARRAY<STRING>[foo,bar] where elements are unquoted identifiers rather than quoted strings or numeric literals.","commonSituations":"Generated expressions that forget to quote strings; mixing boolean/identifier tokens into string arrays; hand-written filters with unquoted values.","solutions":["Quote the offending element as a string literal","Remove the non-literal element or replace it with a valid string","Ensure the expression generator escapes and quotes string values"],"exampleFix":"// before\nARRAY<STRING>[abc, 'def']\n// after\nARRAY<STRING>['abc', 'def']","handlingStrategy":"validation","validationCode":"// Java: require quoted strings (or coercible numerics/NULL) for ARRAY<STRING>\nstatic boolean isValidExplicitStringArrayElement(String e) {\n  return e.equals(\"NULL\")\n      || (e.startsWith(\"'\") && e.endsWith(\"'\"))\n      || e.matches(\"-?\\\\d+(\\\\.\\\\d+)?([eE][-?+]?\\\\d+)?\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Quote identifiers before emitting them into string arrays","Only emit string, numeric, or NULL literals in ARRAY<STRING>","Escape string values with Druid's escape rules","Run generated expressions through Parser.parse in CI as a guardrail"],"tags":["druid","expression-parser","array-literal","string-literal"],"backgroundTag":"invalid-argument-format","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}