Skip to content

[BUG] PromQL queries fail with InvalidTypeIdException when metric has a label named "type" #5684

Description

@robertpaschedag

What is the bug?
Any PromQL query that returns metrics containing a label named "type" fails with:

Could not resolve subtype of [simple type, class org.opensearch.sql.directquery.transport.model.datasource.PrometheusResult]: missing type id property 'type'

For example, avg by (type) (some_metric) or simply querying any metric that has a type label in its label set causes the error. All other label names work correctly.
The root cause is in DataSourceResult.java (line 17):

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")

This Jackson annotation declares "type" as the polymorphic type discriminator for DataSourceResult subtypes. When the Prometheus response contains a metric label called "type" anywhere in the JSON structure (e.g., {"metric": {"type": "some_value"}, "values": [...]}), Jackson mistakenly interprets it as the type discriminator instead of treating it as data, causing deserialization to fail.
How can one reproduce the bug?

  1. Set up a Prometheus data connection in OpenSearch
  2. Have any metric with a label named type (e.g., via relabeling, OTel transform processor, or native metric exposition)
  3. In OpenSearch Dashboards, open the Metrics Explorer or PromQL editor
  4. Execute a query that includes the type label in results, e.g.:
    • avg by (type) (my_metric)
    • Or simply select a metric that has a type label
  5. Observe the InvalidTypeIdException error
    Reproduced with both VictoriaMetrics and vanilla Prometheus as backends.
    What is the expected behavior?
    The query should execute successfully and return results with the type label as a regular metric label, just like any other label name (e.g., instance, job, container). The label name "type" is a perfectly valid Prometheus label and should not conflict with internal deserialization mechanics.
    What is your host/environment?
  • OpenSearch version: 3.7.0
  • Tested with: Prometheus (vanilla) and VictoriaMetrics as data sources
  • OpenSearch Dashboards with query_enhancements plugin
    Do you have any screenshots?
    Do you have any additional context?
    Affected file: direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/DataSourceResult.java
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({@JsonSubTypes.Type(value = PrometheusResult.class, name = "prometheus")})
public interface DataSourceResult {}

Proposed fix (identified with assistance of AI):
Change the property value in the @JsonTypeInfo annotation to a name that cannot collide with valid Prometheus label names. For example:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "@datasource_type")
@JsonSubTypes({@JsonSubTypes.Type(value = PrometheusResult.class, name = "prometheus")})
public interface DataSourceResult {}

Alternative approaches:

  • Use JsonTypeInfo.As.WRAPPER_OBJECT instead of As.PROPERTY to avoid any flat-field collision
  • Use JsonTypeInfo.As.EXISTING_PROPERTY with an explicit dedicated field not exposed in the metric labels
    The key constraint is that "type" is a valid and commonly-used Prometheus metric label (e.g., kube_pod_info{type="..."}) and must not be reserved by the deserialization framework.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions