apache/druid · error · QueryDriver.RequestError

Invalid parameter type:

Error message

Invalid parameter type: 

What it means

translateParameter converts a gRPC QueryParameter's protobuf Value into a Druid SqlParameter. It handles STRING, and treats NULL_VALUE/VALUE_NOT_SET as null; any other value case (e.g. number, bool, array) hits the default branch and throws RequestError("Invalid parameter type: ..."), because the gRPC SQL interface only supports string-typed (VARCHAR) query parameters.

Source

Thrown at extensions-contrib/grpc-query/src/main/java/org/apache/druid/grpc/server/QueryDriver.java:374

    }
    return params;
  }

  private SqlParameter translateParameter(QueryParameter value)
  {
    switch (value.getValueCase()) {
      case DOUBLEVALUE:
        return new SqlParameter(SqlType.DOUBLE, value.getDoubleValue());
      case LONGVALUE:
        return new SqlParameter(SqlType.BIGINT, value.getLongValue());
      case STRINGVALUE:
        return new SqlParameter(SqlType.VARCHAR, value.getStringValue());
      case NULLVALUE:
      case VALUE_NOT_SET:
        return null;
      case ARRAYVALUE:
      default:
        throw new RequestError("Invalid parameter type: " + value.getValueCase().name());
    }
  }

  /**
   * Translate the column schema from the Druid internal form to the gRPC
   * {@link ColumnSchema} form. Note that since the gRPC response returns the
   * schema, none of the data formats include a header. This makes the data format
   * simpler and cleaner.
   */
  private Iterable<? extends ColumnSchema> encodeSqlColumns(SqlRowTransformer rowTransformer)
  {
    RelDataType rowType = rowTransformer.getRowType();
    final RowSignature signature = RowSignatures.fromRelDataType(rowType.getFieldNames(), rowType);
    List<ColumnSchema> cols = new ArrayList<>();
    for (int i = 0; i < rowType.getFieldCount(); i++) {
      ColumnSchema col = ColumnSchema.newBuilder()
                                     .setName(signature.getColumnName(i))
                                     .setSqlType(rowType.getFieldList().get(i).getType().getSqlTypeName().getName())

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Wrap every parameter value as a StringValue in the gRPC request (e.g. Value.newBuilder().setStringValue("42")) and cast in SQL if needed.
  2. For truly NULL parameters, use NULL_VALUE or leave the value unset rather than a typed empty value.
  3. Update the calling code so numbers/booleans are stringified before being placed into QueryParameter.
  4. If array parameters are needed, check the extension version for array support or restructure the SQL to avoid array parameters.

Example fix

// before
Value v = Value.newBuilder().setInt32Value(42).build();
// after
Value v = Value.newBuilder().setStringValue("42").build();
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard parameter values before building the protobuf request
static boolean isSupportedParamValue(Object v) {
  return v == null || v instanceof String; // only string/NULL parameters supported
}

Type guard

boolean isStringValue(com.google.protobuf.Value v) {
  return v.getKindCase() == com.google.protobuf.Value.KindCase.STRING_VALUE
      || v.getKindCase() == com.google.protobuf.Value.KindCase.NULL_VALUE
      || v.getKindCase() == com.google.protobuf.Value.KindCase.KIND_NOT_SET;
}

Try / catch

try {
  return stub.query(req);
} catch (StatusRuntimeException e) {
  if (e.getStatus().getDescription() != null && e.getStatus().getDescription().startsWith("Invalid parameter type")) {
    throw new IllegalArgumentException("Only VARCHAR (string) and NULL parameters are supported", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Submitting a gRPC SQL query whose QueryParameter.value is set to a non-string oneof case — e.g. Int32Value, BoolValue, Struct, or ArrayValue — instead of a StringValue (or leaving the case as something other than NULLVALUE/VALUE_NOT_SET).

Common situations: Client SDK auto-converts a language number/boolean into a typed protobuf Value instead of wrapping it in a string; hand-built protobuf requests that set a typed field; code generated against a newer request schema passing arrays.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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