apache/druid · error · ExpressionValidationException

first argument must be constant STRING expression containing

Error message

first argument must be constant STRING expression containing a valid complex type name but got NULL instead

What it means

Same complex_decode_base64 first-argument validation in BuiltInExprMacros.java, but this variant fires when the first argument is a literal that is explicitly NULL. A NULL literal cannot name a complex type, so validation fails before any decoding happens.

Source

Thrown at processing/src/main/java/org/apache/druid/math/expr/BuiltInExprMacros.java:73

    final class ComplexDecodeBase64Expression extends ExprMacroTable.BaseScalarMacroFunctionExpr
    {
      private final ExpressionType complexType;
      private final TypeStrategy<?> typeStrategy;

      public ComplexDecodeBase64Expression(List<Expr> args)
      {
        super(ComplexDecodeBase64ExprMacro.this, args);
        validationHelperCheckArgumentCount(args, 2);
        final Expr arg0 = args.get(0);

        if (!arg0.isLiteral()) {
          throw validationFailed(
              "first argument must be constant STRING expression containing a valid complex type name but got '%s' instead",
              arg0.stringify()
          );
        }
        if (arg0.isNullLiteral()) {
          throw validationFailed("first argument must be constant STRING expression containing a valid complex type name but got NULL instead");
        }
        final Object literal = arg0.getLiteralValue();
        if (!(literal instanceof String)) {
          throw validationFailed(
              "first argument must be constant STRING expression containing a valid complex type name but got '%s' instead",
              arg0.getLiteralValue()
          );
        }

        this.complexType = ExpressionTypeFactory.getInstance().ofComplex((String) literal);
        try {
          this.typeStrategy = complexType.getStrategy();
        }
        catch (IllegalArgumentException illegal) {
          throw validationFailed(
              "first argument must be a valid COMPLEX type name, got unknown COMPLEX type [%s]",
              complexType.asTypeString()
          );

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Pass a non-null constant complex type name string as the first argument.
  2. Check application code for unbound/optional parameters that default to NULL.
  3. Verify the parameter substitution in any SQL templating layer.
  4. If type varies per row, decode outside SQL or use a per-type query.

Example fix

// before
complex_decode_base64(NULL, base64_col)
// after
complex_decode_base64('druid.metrics.snapshot', base64_col)
Defensive patterns

Strategy: validation

When it happens

Trigger: Calling complex_decode_base64(NULL, data_col) — first argument is a literal NULL string.

Common situations: Templated/parameterized SQL where the type-name bind variable was never bound or was bound to NULL; generated SQL from an app where an optional type parameter was omitted.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1f217482db37e311. Report an issue: GitHub.