crowdsecurity/crowdsec · error · InvalidFilter

invalid contains value: %w: %w

Error message

invalid contains value: %w: %w

What it means

Returned by alertPredicatesFromFilter when the 'contains' query parameter cannot be parsed as a boolean via strconv.ParseBool. The parse error is wrapped together with the InvalidFilter sentinel, marking the request filter as invalid.

Source

Thrown at pkg/database/alertfilter.go:202

		err               error
		hasActiveDecision bool
		rng               csnet.Range
	)

	contains := true

	// if contains is true, return bans that *contains* the given value (value is the inner)
	// else, return bans that are *contained* by the given value (value is the outer)

	handleSimulatedFilter(filter, &predicates)
	handleOriginFilter(filter)

	for param, value := range filter {
		switch param {
		case "contains":
			contains, err = strconv.ParseBool(value[0])
			if err != nil {
				return nil, fmt.Errorf("invalid contains value: %w: %w", err, InvalidFilter)
			}
		case "scope":
			handleScopeFilter(value[0], &predicates)
		case "value":
			predicates = append(predicates, alert.SourceValueEQ(value[0]))
		case "scenario":
			predicates = append(predicates, alert.Or(
				alert.ScenarioEQ(value[0]), // match alerts with no decisions
				alert.HasDecisionsWith(decision.ScenarioEQ(value[0])),
			))
		case "ip", "range":
			rng, err = csnet.NewRange(value[0])
			if err != nil {
				return nil, err
			}
		case "since", "created_before", "until":
			if err := handleTimeFilters(param, value[0], &predicates); err != nil {
				return nil, err

View on GitHub (pinned to 909b515798)

Solutions

  1. Use only strconv-accepted booleans: true/false, 1/0, t/f, TRUE/FALSE etc. (e.g. ?contains=true).
  2. Fix the calling script/integration to emit lowercase true/false.
  3. Validate client-side before sending: strconv.ParseBool(value) in Go or equivalent.
  4. If a bouncer/integration sends this, update it — 'yes'/'no' are not accepted.

Example fix

// before
GET /v1/alerts?contains=yes
// after
GET /v1/alerts?contains=true
Defensive patterns

Strategy: validation

Validate before calling

if _, err := strconv.ParseBool(containsVal); err != nil {
    return fmt.Errorf("contains must be a Go boolean (true/false/1/0), got %q", containsVal)
}

Try / catch

_, err := client.Alerts.List(ctx, models.GetAlertsOpts{Contains: &contains})
var apiErr *crowdsec.ApiErrorResponse
if err != nil && errors.As(err, &apiErr) && apiErr.Message != nil {
    // 400: fix the query parameter and retry once with corrected value
}

Prevention

When it happens

Trigger: A LAPI alerts query (applyAlertFilter or DeleteAlertWithFilter) passes contains=<not-bool>, e.g. contains=yes, contains=1.0, or contains= (empty).

Common situations: Hand-written curl calls using 'true/false' variants outside strconv's accepted set (1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False), or UI clients sending localized booleans.

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/4d05a0fbfc624d3b. Report an issue: GitHub.