{"record":{"id":"230ad2619d81c742","repo":"crowdsecurity/crowdsec","slug":"invalid-offset-value-w-w","errorCode":null,"errorMessage":"invalid offset value: %w: %w","messagePattern":"invalid offset value: %w: %w","errorType":"validation","errorClass":"InvalidFilter","httpStatus":null,"severity":"warning","filePath":"pkg/database/decisionfilter.go","lineNumber":92,"sourceCode":"\t\t\t\t\tpredicates...,\n\t\t\t\t),\n\t\t\t))\n\t\tcase \"ip\", \"range\":\n\t\t\trng, err = csnet.NewRange(value[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"unable to convert '%s' to int: %w: %w\", value[0], err, InvalidIPOrRange)\n\t\t\t}\n\t\tcase \"limit\":\n\t\t\tlimit, err := strconv.Atoi(value[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid limit value: %w: %w\", err, InvalidFilter)\n\t\t\t}\n\n\t\t\tquery = query.Limit(limit)\n\t\tcase \"offset\":\n\t\t\toffset, err := strconv.Atoi(value[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid offset value: %w: %w\", err, InvalidFilter)\n\t\t\t}\n\n\t\t\tquery = query.Offset(offset)\n\t\tcase \"id_gt\":\n\t\t\tid, err := strconv.Atoi(value[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid id_gt value: %w: %w\", err, InvalidFilter)\n\t\t\t}\n\n\t\t\tquery = query.Where(decision.IDGT(id))\n\t\t}\n\t}\n\n\tquery, err = decisionIPFilter(query, contains, rng)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to apply StartIpEndIpFilter: %w\", err)\n\t}\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/database/decisionfilter.go#L74-L110","documentation":"applyDecisionFilter rejects the request because the 'offset' query parameter is not a valid integer (strconv.Atoi fails). Wrapped with the InvalidFilter sentinel for programmatic identification by LAPI clients.","triggerScenarios":"GET /v1/decisions?offset=ten or an empty ?offset= on decisions listing endpoints using QueryDecisionWithFilter.","commonSituations":"Pagination loops where a page counter became NaN/empty before URL construction; copy-pasted query strings with units ('offset=10items').","solutions":["Send a plain non-negative integer for offset (e.g. ?offset=50).","Omit offset when not paginating.","Validate/sanitize the numeric parameter client-side before the request.","Log the full query string when building pagination loops to spot empty values."],"exampleFix":"// before\nGET /v1/decisions?offset=\n// after\nGET /v1/decisions?offset=50","handlingStrategy":"validation","validationCode":"offset, err := strconv.Atoi(offsetRaw)\nif err != nil || offset < 0 {\n    offset = 0\n}\n// then use offset in the request","typeGuard":null,"tryCatchPattern":"resp, err := lapi.GetDecisions(ctx, models.GetDecisionsOpts{Offset: &offset})\nif err != nil && strings.Contains(err.Error(), \"invalid offset value\") {\n    return fmt.Errorf(\"offset must be an integer, got %q\", offsetRaw)\n}","preventionTips":["Reset pagination counters on errors so they never go NaN/empty","Clamp offset to >= 0 client-side","Use url.Values for query construction","Log full request URLs when paginating"],"tags":["api","query-parameter","pagination","validation"],"backgroundTag":"invalid-query-parameter","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}