Skip to content

fix(promlib): add lenient type coercion to ParsePromOptions for API/Terraform stored fields [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT] - #303

Open
waterWang wants to merge 1 commit into
grafana:mainfrom
waterWang:fix/parse-prom-options-lenient-type-coercion
Open

fix(promlib): add lenient type coercion to ParsePromOptions for API/Terraform stored fields [fj4WqyCCw3C5ShR1RfB7MoBPTpkRrBFYP1uT35g3MvT]#303
waterWang wants to merge 1 commit into
grafana:mainfrom
waterWang:fix/parse-prom-options-lenient-type-coercion

Conversation

@waterWang

Copy link
Copy Markdown

Description

Fixes grafana/grafana#130119

Since promlib v0.0.13, ParsePromOptions() uses strict JSON unmarshaling. Datasources provisioned through the API or Terraform can store values with off-spec types (e.g., string "true" for a bool field, number 15 for a string field, or a single object instead of a one-element array). When that happens, instance creation fails and every query/resource call against that datasource errors immediately.

This PR adds a lenient fallback with type coercion:

  • Boolean fields: accept string "true"/"false"/"1"/"0"/"yes"/"no" and number 0/1
  • String fields: accept numbers (e.g., "timeInterval": 15)
  • *int64 fields: accept string numbers and float64
  • float64 fields: accept string numbers
  • ExemplarTraceIDDestination: accept a single object (wraps into a one-element array)

The coercion only runs when strict unmarshal fails, so it has zero overhead for datasources with correctly typed fields.

Verification

  • manageAlerts: "true" (string→bool) → no longer fails
  • seriesLimit: "100" (string→*int64) → no longer fails
  • timeInterval: 15 (number→string) → no longer fails
  • exemplarTraceIdDestinations: {...} (object→array) → no longer fails
  • Correctly typed fields continue to use the fast path

@waterWang
waterWang requested a review from a team as a code owner August 5, 2026 11:22
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Signed commits report

1 of 1 commit between main and fix/parse-prom-options-lenient-type-coercion could not be fully verified:

Commit Author Reason Message
f0302e85 water unsigned fix(promlib): add lenient type coercion to ParsePromOptions for API/Terraform stored fields

This repository requires all commits to be signed. See GitHub docs on commit signature verification.

@cla-assistant

cla-assistant Bot commented Aug 5, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

// for a string field). The UI always writes normalized types, and the
// previous schemaless reader accepted both.
raw := make(map[string]any)
if err2 := json.Unmarshal(data, &raw); err2 != nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if err2 := json.Unmarshal(data, &raw); err2 != nil {
if err = json.Unmarshal(data, &raw); err != nil {

if v, ok := raw[key]; ok {
switch val := v.(type) {
case string:
raw[key] = val == "true" || val == "1" || val == "yes"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should accept yes, no, 0, or 1, as boolean values. Modern YAML is strict and only accepts true or false.

"incrementalQuerying", "disableRecordingRules",
"oauthPassThru", "seriesEndpoint", "disableGrafanaCache",
} {
if v, ok := raw[key]; ok {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a value cannot be coerced we should return a relevant error.

"alertmanagerUid", "authType", "defaultRegion", "profile",
} {
if v, ok := raw[key]; ok {
if num, ok := v.(float64); ok {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the coercion is not ok we should return an error.

}

// *int64 fields: accept string numbers and float64.
if v, ok := raw["seriesLimit"]; ok {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here please.

if v, ok := raw["seriesLimit"]; ok {
switch val := v.(type) {
case string:
if n, err := strconv.ParseInt(val, 10, 64); err == nil {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error here should be returned.

@aangelisc aangelisc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, could you also add tests please 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prometheus datasources: strict typed jsonData parsing in promlib >= 0.0.13 fails instance creation for stored off-type fields

2 participants