{"record":{"id":"7691147384bd5586","repo":"jaegertracing/jaeger","slug":"s-must-be-before-s","errorCode":null,"errorMessage":"%s must be before %s","messagePattern":"(.+?) must be before (.+?)","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/query_parser.go","lineNumber":114,"sourceCode":"\t\t}\n\t\tqueryParams.Filter = filter\n\t}\n\n\ttimeMinStr, timeMinParam := getQueryParam(q, paramTimeMin, paramTimeMinDeprecated)\n\ttimeMaxStr, timeMaxParam := getQueryParam(q, paramTimeMax, paramTimeMaxDeprecated)\n\tif timeMinStr == \"\" || timeMaxStr == \"\" {\n\t\treturn nil, fmt.Errorf(\"%s and %s are required\", paramTimeMin, paramTimeMax)\n\t}\n\ttimeMinParsed, err := time.Parse(time.RFC3339Nano, timeMinStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed parameter %s: %w\", timeMinParam, err)\n\t}\n\ttimeMaxParsed, err := time.Parse(time.RFC3339Nano, timeMaxStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed parameter %s: %w\", timeMaxParam, err)\n\t}\n\tif !timeMinParsed.Before(timeMaxParsed) {\n\t\treturn nil, fmt.Errorf(\"%s must be before %s\", paramTimeMin, paramTimeMax)\n\t}\n\tqueryParams.StartTimeMin = timeMinParsed\n\tqueryParams.StartTimeMax = timeMaxParsed\n\n\tn, searchDepthParam := getQueryParam(q, paramSearchDepth, paramSearchDepthDeprecated)\n\tif n == \"\" {\n\t\tn = q.Get(paramNumTraces)\n\t\tsearchDepthParam = paramNumTraces\n\t}\n\tif n != \"\" {\n\t\tsearchDepth, err := strconv.Atoi(n)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"malformed parameter %s: %w\", searchDepthParam, err)\n\t\t}\n\t\tqueryParams.SearchDepth = searchDepth\n\t} else {\n\t\tqueryParams.SearchDepth = defaultSearchDepth\n\t}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/apiv3/query_parser.go#L96-L132","documentation":"After both timestamps parse, Jaeger enforces a strict ordering: query.startTimeMin must be strictly before query.startTimeMax. Equal or inverted bounds are rejected with this message.","triggerScenarios":"GET /api/v3/traces where query.startTimeMin >= query.startTimeMax - e.g. both set to the same instant, or min/max swapped by a client that builds the range from unsorted values.","commonSituations":"Swapped variables when constructing the URL; a zero-length window (min == max) which the API does not allow; clients that clamp both bounds to 'now'.","solutions":["Swap the values so the earlier timestamp is in query.startTimeMin.","Ensure min < max strictly; if you need a point-in-time lookup use trace_id lookup endpoints instead.","Add client-side validation before sending: new Date(min) < new Date(max)."],"exampleFix":"// before (swapped)\nquery.startTimeMin=2026-01-02T00:00:00Z&query.startTimeMax=2026-01-01T00:00:00Z\n// after\nquery.startTimeMin=2026-01-01T00:00:00Z&query.startTimeMax=2026-01-02T00:00:00Z","handlingStrategy":"validation","validationCode":"func checkRange(minStr, maxStr string) error {\n\tmin, err1 := time.Parse(time.RFC3339Nano, minStr)\n\tmax, err2 := time.Parse(time.RFC3339Nano, maxStr)\n\tif err1 != nil || err2 != nil { return errors.New(\"bad timestamps\") }\n\tif !min.Before(max) { return errors.New(\"startTimeMin must be before startTimeMax\") }\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if resp.StatusCode == 400 {\n\treturn fmt.Errorf(\"time range rejected: %s\", mustRead(resp.Body))\n}","preventionTips":["Construct ranges via a helper that takes (start, end) in order, never min/max as separate ad-hoc params.","Clamp end = max(start+epsilon, end) when both bounds may coincide.","Add a unit test that min == max is rejected before sending."],"tags":["http","query-params","validation","datetime","api-v3"],"backgroundTag":"invalid-time-range","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}