thanos-io/thanos · error

add thanos opts query params

Error message

add thanos opts query params

What it means

QueryInstant calls opts.AddTo(params) to append Thanos-specific parameters (partial_response etc.) to the parsed query. If AddTo rejects the options — which happens only for an unknown PartialResponseStrategy — it wraps the failure as 'add thanos opts query params'. See also error 'unknown partial response strategy %v' (657), which is the root cause.

Solutions

  1. Pass storepb.PartialResponseStrategy_WARN or _ABORT explicitly in QueryOptions
  2. Unwrap the chained error to confirm the unknown-strategy root cause
  3. Validate strategy values at config-load time before they reach query code
  4. Set DoNotAddThanosParams=true if querying vanilla Prometheus where Thanos params are unnecessary

Example fix

// before
opts := promclient.QueryOptions{}
vec, _, _, err := client.QueryInstant(ctx, base, `up`, time.Now(), opts)
// after
opts := promclient.QueryOptions{PartialResponseStrategy: storepb.PartialResponseStrategy_ABORT}
vec, _, _, err := client.QueryInstant(ctx, base, `up`, time.Now(), opts)
Defensive patterns

Strategy: validation

Validate before calling

if opts.PartialResponseStrategy != storepb.PartialResponseStrategy_WARN &&
    opts.PartialResponseStrategy != storepb.PartialResponseStrategy_ABORT {
    return fmt.Errorf("invalid strategy %v before query", opts.PartialResponseStrategy)
}

Type guard

func optsValid(o promclient.QueryOptions) bool {
    return o.PartialResponseStrategy == storepb.PartialResponseStrategy_WARN ||
        o.PartialResponseStrategy == storepb.PartialResponseStrategy_ABORT
}

Try / catch

vec, _, _, err := client.QueryInstant(ctx, base, query, t, opts)
if err != nil && strings.Contains(err.Error(), "add thanos opts query params") {
    return fmt.Errorf("fix QueryOptions strategy: %w", err)
}

Prevention

When it happens

Trigger: Calling QueryInstant with QueryOptions whose PartialResponseStrategy is neither WARN nor ABORT; the inner AddTo error is wrapped and re-raised by this message.

Common situations: Same root causes as the unknown-strategy error: zero-value enums from unvalidated config, enum type drift across Thanos versions, copying options between incompatible code paths.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/2cc631819cdad518. Report an issue: GitHub.

Appendix: source

Thrown at pkg/promclient/promclient.go:436

	return nil
}

type Explanation struct {
	Name     string         `json:"name"`
	Children []*Explanation `json:"children,omitempty"`
}

// QueryInstant performs an instant query using a default HTTP client and returns results in model.Vector type.
func (c *Client) QueryInstant(ctx context.Context, base *url.URL, query string, t time.Time, opts QueryOptions) (model.Vector, []string, *Explanation, error) {
	params, err := url.ParseQuery(base.RawQuery)
	if err != nil {
		return nil, nil, nil, errors.Wrapf(err, "parse raw query %s", base.RawQuery)
	}
	params.Add("query", query)
	params.Add("time", t.Format(time.RFC3339Nano))
	if !opts.DoNotAddThanosParams {
		if err := opts.AddTo(params); err != nil {
			return nil, nil, nil, errors.Wrap(err, "add thanos opts query params")
		}
	}

	u := *base
	u.Path = path.Join(u.Path, "/api/v1/query")
	u.RawQuery = params.Encode()

	level.Debug(c.logger).Log("msg", "querying instant", "url", u.String())

	span, ctx := tracing.StartSpan(ctx, "/prom_query_instant HTTP[client]")
	defer span.Finish()

	method := opts.Method
	if method == "" {
		method = http.MethodGet
	}

	body, _, err := c.req2xx(ctx, &u, method, opts.HTTPHeaders)

View on GitHub (pinned to 35b8b99117)