opensearch-project / opensearch-project/sql
[BUG] PromQL queries fail with InvalidTypeIdException when metric has a label named "type"
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 176
- Forks
- 229
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 43
Description
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?
- Set up a Prometheus data connection in OpenSearch
- Have any metric with a label named
type(e.g., via relabeling, OTel transform processor, or native metric exposition) - In OpenSearch Dashboards, open the Metrics Explorer or PromQL editor
- Execute a query that includes the
typelabel in results, e.g.:avg by (type) (my_metric)- Or simply select a metric that has a
typelabel
- Observe the
InvalidTypeIdExceptionerror
Reproduced with both VictoriaMetrics and vanilla Prometheus as backends.
What is the expected behavior?
The query should execute successfully and return results with thetypelabel 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_enhancementsplugin
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_OBJECTinstead ofAs.PROPERTYto avoid any flat-field collision - Use
JsonTypeInfo.As.EXISTING_PROPERTYwith 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in direct-query/src/main/java/org/opensearch/sql/directquery/transport/model/datasource/DataSourceResult.java and inspect how its Jackson subtype annotation handles the type property. Reproduce the failure with a PromQL query returning a metric label named type; done means the query succeeds and preserves type as a regular Prometheus label without InvalidTypeIdException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, prometheus
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 74/100