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
- Pass a non-null constant complex type name string as the first argument.
- Check application code for unbound/optional parameters that default to NULL.
- Verify the parameter substitution in any SQL templating layer.
- 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
- first argument must be constant STRING expression containing
- needs a LONG as its second argument but got null
- Cannot translate sqlTypeName[%s] to Druid type for field[%s]
- Unknown
- Unsupported unknown value type
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/1f217482db37e311.
Report an issue: GitHub.