{"record":{"id":"e1a7393a145ac392","repo":"thanos-io/thanos","slug":"invalid-parameter-q-v","errorCode":null,"errorMessage":"invalid parameter %q; %v","messagePattern":"invalid parameter %q; (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cortex/querier/queryrange/query_range.go","lineNumber":891,"sourceCode":"\t}\n\treturn 0, httpgrpc.Errorf(http.StatusBadRequest, \"cannot parse %q to a valid duration\", s)\n}\n\nfunc encodeTime(t int64) string {\n\tf := float64(t) / 1.0e3\n\treturn strconv.FormatFloat(f, 'f', -1, 64)\n}\n\nfunc encodeDurationMs(d int64) string {\n\treturn strconv.FormatFloat(float64(d)/float64(time.Second/time.Millisecond), 'f', -1, 64)\n}\n\nfunc decorateWithParamName(err error, field string) error {\n\terrTmpl := \"invalid parameter %q; %v\"\n\tif status, ok := status.FromError(err); ok {\n\t\treturn httpgrpc.Errorf(int(status.Code()), errTmpl, field, status.Message())\n\t}\n\treturn fmt.Errorf(errTmpl, field, err)\n}\n\nfunc PrometheusResponseQueryableSamplesStatsPerStepJsoniterDecode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {\n\tif !iter.ReadArray() {\n\t\titer.ReportError(\"queryrange.PrometheusResponseQueryableSamplesStatsPerStep\", \"expected [\")\n\t\treturn\n\t}\n\n\tt := model.Time(iter.ReadFloat64() * float64(time.Second/time.Millisecond))\n\n\tif !iter.ReadArray() {\n\t\titer.ReportError(\"queryrange.PrometheusResponseQueryableSamplesStatsPerStep\", \"expected ,\")\n\t\treturn\n\t}\n\tv := iter.ReadInt64()\n\n\tif iter.ReadArray() {\n\t\titer.ReportError(\"queryrange.PrometheusResponseQueryableSamplesStatsPerStep\", \"expected ]\")","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/internal/cortex/querier/queryrange/query_range.go#L873-L909","documentation":"decorateWithParamName wraps errors from decoding/validating a query-range request parameter, producing 'invalid parameter \"<field>\"; <detail>'. If the error is a gRPC status error it becomes an httpgrpc HTTP error carrying the status code; otherwise it is a plain fmt.Errorf.","triggerScenarios":"Calling a query-range endpoint (Prometheus API path through queryrange middleware) with a malformed parameter value that downstream gRPC decoding rejects — e.g. bad timeout, invalid step, unparseable start/end timestamps.","commonSituations":"Dashboards sending step/timeout values with wrong units; start/end outside retention; query parameter strings that fail protobuf/JSON decoding in the query-frontend.","solutions":["Read the field name and detail in the message to see which parameter is invalid.","Fix the client request: use valid duration formats (e.g. '1h'), numeric timestamps in seconds, and a step > 0.","Check start/end are within the configured retention/query window.","Catch the httpgrpc error client-side and surface the parameter name back to the user instead of a generic 500."],"exampleFix":"// before\n/api/v1/query_range?query=up&start=now-1h&end=now&step=0\n// after\n/api/v1/query_range?query=up&start=1690000000&end=1690003600&step=15","handlingStrategy":"validation","validationCode":"func validQueryRange(start, end int64, step time.Duration) error {\n    if step <= 0 { return fmt.Errorf(\"step must be > 0\") }\n    if start >= end { return fmt.Errorf(\"start must be before end\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"resp, err := frontend.QueryRange(ctx, req)\nif err != nil {\n    var hg httpgrpc.HTTPClientError\n    if errors.As(err, &hg) && strings.Contains(err.Error(), \"invalid parameter\") {\n        return http.StatusBadRequest // surface which param is bad\n    }\n    return err\n}","preventionTips":["Validate duration/step/timestamp formats client-side before sending.","Keep start/end within retention and use epoch seconds.","Surface the parameter name from the error message to end users."],"tags":["query-range","validation","http"],"backgroundTag":"invalid-query-parameter","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}