{"record":{"id":"f588234344b54d44","repo":"thanos-io/thanos","slug":"limit-must-be-non-negative","errorCode":null,"errorMessage":"limit must be non-negative","messagePattern":"limit must be non-negative","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"pkg/api/query/v1.go","lineNumber":1627,"sourceCode":"\t}\n\tif d, err := model.ParseDuration(s); err == nil {\n\t\treturn time.Duration(d), nil\n\t}\n\treturn 0, errors.Errorf(\"cannot parse %q to a valid duration\", s)\n}\n\n// parseLimitParam returning 0 means no limit is to be applied.\nfunc parseLimitParam(s string) (int, error) {\n\tif s == \"\" {\n\t\treturn 0, nil\n\t}\n\n\tlimit, err := strconv.Atoi(s)\n\tif err != nil {\n\t\treturn 0, errors.Errorf(\"cannot parse %q to a valid limit\", s)\n\t}\n\tif limit < 0 {\n\t\treturn 0, errors.New(\"limit must be non-negative\")\n\t}\n\n\treturn limit, nil\n}\n\n// toHintLimit increases the API limit, as returned by parseLimitParam, by 1.\n// This allows for emitting warnings when the results are truncated.\nfunc toHintLimit(limit int) int {\n\t// 0 means no limit and avoid int overflow\n\tif limit > 0 && limit < math.MaxInt {\n\t\treturn limit + 1\n\t}\n\treturn limit\n}\n\n// NewMetricMetadataHandler creates handler compatible with HTTP /api/v1/metadata https://prometheus.io/docs/prometheus/latest/querying/api/#querying-metric-metadata\n// which uses gRPC Unary Metadata API.\nfunc NewMetricMetadataHandler(client metadata.UnaryClient, enablePartialResponse bool) func(*http.Request) (any, []error, *api.ApiError, func()) {","sourceCodeStart":1609,"sourceCodeEnd":1645,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/api/query/v1.go#L1609-L1645","documentation":"A validation guard in parseLimitParam: the limit query parameter parsed successfully as an integer but is negative. Limits of 0 mean 'no limit', so negative values are meaningless and the request is rejected as bad data before the limit is applied.","triggerScenarios":"Requesting any limit-accepting endpoint with `?limit=-1` (or any negative number).","commonSituations":"Code computing limits by subtraction (e.g. remaining = budget - used) that went negative; CLI/SDK defaults of -1 meaning 'unlimited' being passed through to Thanos which does not accept -1 as unlimited.","solutions":["Use a non-negative limit value","Omit the parameter for unlimited results"],"exampleFix":"// before\nlimit := remaining // -1 when budget exhausted\nurl := fmt.Sprintf(\"/api/v1/labels?limit=%d\", limit)\n// after\nif limit < 0 { limit = 0 }\nurl := fmt.Sprintf(\"/api/v1/labels?limit=%d\", limit)","handlingStrategy":"validation","validationCode":"function validLimit(s) { const n = parseInt(s, 10); return Number.isInteger(n) && n >= 0; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp computed limits with Math.max(0, n).","Do not use -1 as an 'unlimited' sentinel with Thanos; omit the param instead.","Test negative-value paths in client code."],"tags":["limit","bad-request","validation","query-api"],"backgroundTag":"invalid-argument-value","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"}