crowdsecurity/crowdsec · warning · InvalidFilter

invalid limit value: %w: %w

Error message

invalid limit value: %w: %w

What it means

applyDecisionFilter rejects the request because the 'limit' query parameter is not a valid integer (strconv.Atoi fails). The error is wrapped with the InvalidFilter sentinel so LAPI callers can classify it as a bad filter value.

Source

Thrown at pkg/database/decisionfilter.go:85

		case "scenarios_containing":
			predicates := decisionPredicatesFromStr(value[0], decision.ScenarioContainsFold)
			query = query.Where(decision.Or(predicates...))
		case "scenarios_not_containing":
			predicates := decisionPredicatesFromStr(value[0], decision.ScenarioContainsFold)
			query = query.Where(decision.Not(
				decision.Or(
					predicates...,
				),
			))
		case "ip", "range":
			rng, err = csnet.NewRange(value[0])
			if err != nil {
				return nil, fmt.Errorf("unable to convert '%s' to int: %w: %w", value[0], err, InvalidIPOrRange)
			}
		case "limit":
			limit, err := strconv.Atoi(value[0])
			if err != nil {
				return nil, fmt.Errorf("invalid limit value: %w: %w", err, InvalidFilter)
			}

			query = query.Limit(limit)
		case "offset":
			offset, err := strconv.Atoi(value[0])
			if err != nil {
				return nil, fmt.Errorf("invalid offset value: %w: %w", err, InvalidFilter)
			}

			query = query.Offset(offset)
		case "id_gt":
			id, err := strconv.Atoi(value[0])
			if err != nil {
				return nil, fmt.Errorf("invalid id_gt value: %w: %w", err, InvalidFilter)
			}

			query = query.Where(decision.IDGT(id))
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Send a plain integer for limit (e.g. ?limit=100).
  2. Omit the limit parameter when you don't need pagination.
  3. Validate with strconv.Atoi (or equivalent) on the client before building the URL.
  4. Check the wrapped strconv error to confirm the offending value.

Example fix

// before
GET /v1/decisions?limit=all
// after
GET /v1/decisions?limit=100
Defensive patterns

Strategy: validation

Validate before calling

func validInt(v string) bool {
    _, err := strconv.Atoi(v)
    return err == nil
}
if limitParam != "" && !validInt(limitParam) {
    limitParam = "100" // or drop the parameter
}

Try / catch

resp, err := lapi.GetDecisions(ctx, models.GetDecisionsOpts{Limit: &limit})
if err != nil && strings.Contains(err.Error(), "invalid limit value") {
    return fmt.Errorf("limit must be an integer, got %q", limitRaw)
}

Prevention

When it happens

Trigger: GET /v1/decisions?limit=abc or ?limit= (empty) or a float like ?limit=10.5 on any decisions endpoint that goes through QueryDecisionWithFilter.

Common situations: Shell scripts building query strings from untyped variables; copying 'limit=all' from another API; locale-formatted numbers with separators (1,000).

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/c207485bd8e0e601. Report an issue: GitHub.