thanos-io/thanos · error · ApiError
invalid rules parameter type=
Error message
invalid rules parameter type='%v'
What it means
Returned by the /api/v1/rules endpoint when the 'type' query parameter is a non-empty value that doesn't match a RulesRequest_Type enum value (ALL, ALERT, RECORD, or their variants). Like the targets state check, the value is uppercased and looked up in the protobuf enum map; unknown non-empty values yield ErrorBadData (HTTP 400).
Solutions
- Use one of the accepted values: all, alert, or record (case-insensitive).
- Omit the 'type' parameter to get all rules.
- Consult rulespb.RulesRequest_Type in pkg/store/labelpb or rules proto for exact enum names.
Example fix
// before curl 'http://query:9090/api/v1/rules?type=alerting' // after curl 'http://query:9090/api/v1/rules?type=alert'
Defensive patterns
Strategy: validation
Validate before calling
const allowed = ['all','alert','record'];
const typ = params.get('type');
if (typ && !allowed.includes(typ.toLowerCase())) throw new Error(`invalid type='${typ}'; use all|alert|record`); Prevention
- Map Prometheus 'alerting'/'recording' to 'alert'/'record' before calling Thanos.
- Omit type for the default ALL.
- Centralize enum values in your API client.
When it happens
Trigger: GET /api/v1/rules?type=alerting — only values matching the RulesRequest_Type enum (case-insensitive: all, alert, record) are accepted.
Common situations: Using Prometheus terminology like 'alerting'/'recording' instead of the proto enum values 'alert'/'record', typos, or assuming empty string means invalid — an empty type is allowed and defaults to ALL.
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
- invalid targets parameter state=
- ID cannot be empty
- Action cannot be empty
- unexpected downsampling resolution
- failed to get prometheus version
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/5ec7fc70f82911b5.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/api/query/v1.go:1475
if enablePartialResponse {
ps = storepb.PartialResponseStrategy_WARN
}
return func(r *http.Request) (any, []error, *api.ApiError, func()) {
span, ctx := tracing.StartSpan(r.Context(), "receive_http_request")
defer span.Finish()
var (
groups *rulespb.RuleGroups
warnings annotations.Annotations
err error
)
typeParam := r.URL.Query().Get("type")
typ, ok := rulespb.RulesRequest_Type_value[strings.ToUpper(typeParam)]
if !ok {
if typeParam != "" {
return nil, nil, &api.ApiError{Typ: api.ErrorBadData, Err: errors.Errorf("invalid rules parameter type='%v'", typeParam)}, func() {}
}
typ = int32(rulespb.RulesRequest_ALL)
}
if err := r.ParseForm(); err != nil {
return nil, nil, &api.ApiError{Typ: api.ErrorInternal, Err: errors.Errorf("error parsing request form='%v'", MatcherParam)}, func() {}
}
// TODO(bwplotka): Allow exactly the same functionality as query API: passing replica, dedup and partial response as HTTP params as well.
req := &rulespb.RulesRequest{
Type: rulespb.RulesRequest_Type(typ),
PartialResponseStrategy: ps,
MatcherString: r.Form[MatcherParam],
RuleName: r.Form[RuleNameParam],
RuleGroup: r.Form[RuleGroupParam],
File: r.Form[FileParam],
}
tracing.DoInSpan(ctx, "retrieve_rules", func(ctx context.Context) {View on GitHub (pinned to 35b8b99117)