{"record":{"id":"f6c0488367616c6e","repo":"vitessio/vitess","slug":"requested-limit-is-out-of-range-v-f6c048","errorCode":null,"errorMessage":"requested limit is out of range: %v","messagePattern":"requested limit is out of range: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/engine/memory_sort.go","lineNumber":140,"sourceCode":"}\n\nfunc (ms *MemorySort) fetchCount(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) (int, error) {\n\tif ms.UpperLimit == nil {\n\t\treturn math.MaxInt, nil\n\t}\n\tenv := evalengine.NewExpressionEnv(ctx, bindVars, vcursor)\n\tresolved, err := env.Evaluate(ms.UpperLimit)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tvalue := resolved.Value(vcursor.ConnCollation())\n\tif !value.IsIntegral() {\n\t\treturn 0, sqltypes.ErrIncompatibleTypeCast\n\t}\n\n\tcount, err := strconv.Atoi(value.RawStr())\n\tif err != nil || count < 0 {\n\t\treturn 0, fmt.Errorf(\"requested limit is out of range: %v\", value.RawStr())\n\t}\n\treturn count, nil\n}\n\nfunc (ms *MemorySort) description() PrimitiveDescription {\n\torderByIndexes := GenericJoin(ms.OrderBy, orderByParamsToString)\n\tother := map[string]any{\"OrderBy\": orderByIndexes}\n\tif ms.TruncateColumnCount > 0 {\n\t\tother[\"ResultColumns\"] = ms.TruncateColumnCount\n\t}\n\treturn PrimitiveDescription{\n\t\tOperatorType: \"Sort\",\n\t\tVariant:      \"Memory\",\n\t\tOther:        other,\n\t}\n}\n\nfunc orderByParamsToString(i any) string {","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/engine/memory_sort.go#L122-L158","documentation":"MemorySort.fetchCount validates the LIMIT/OFFSET value used by in-memory sorting; if the value is not a valid non-negative integer (Atoi fails or is negative), this error is returned. It is the MemorySort counterpart of the Limit primitive's identical check.","triggerScenarios":"TryExecute/TryStreamExecute of an ORDER BY query whose LIMIT or OFFSET expression evaluates to a non-integral, non-numeric, negative, or overflow-sized value.","commonSituations":"Negative OFFSET computed from page arithmetic; LIMIT supplied as a float (e.g. 10.5); bind parameter serialized with quotes/spaces; huge values overflowing int.","solutions":["Ensure LIMIT/OFFSET evaluate to non-negative integral values.","Fix page-number arithmetic so offset = (page-1)*size never goes negative.","Coerce or reject fractional/oversized values in application code before executing."],"exampleFix":"// before\noffset := (page - 1) * size // page=0 -> -10\n// after\nif page < 1 { page = 1 }\noffset := (page - 1) * size","handlingStrategy":"validation","validationCode":"if !validLimitOffset(limit) || !validLimitOffset(offset) {\n    return errors.New(\"LIMIT/OFFSET must be non-negative integers\")\n}\nfunc validLimitOffset(v int) bool { return v >= 0 }","typeGuard":"func isNonNegativeInt(v any) bool {\n    n, ok := v.(int)\n    return ok && n >= 0\n}","tryCatchPattern":null,"preventionTips":["Compute OFFSET as (page-1)*size with page >= 1 enforced.","Reject fractional or string-typed limit values at the API boundary.","Bind integers, not floats or formatted strings, for LIMIT parameters."],"tags":["vtgate","limit","memory-sort","input-validation"],"backgroundTag":"invalid-limit-offset-value","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}