crowdsecurity/crowdsec · error · InvalidFilter

'%s' doesn't exist: %w

Error message

'%s' doesn't exist: %w

What it means

ExpireDecisionsWithFilter only supports the filter keys 'contains', 'scopes', 'uuid', 'origin', 'value', 'type', 'ip', 'range' and 'scenario'. Any other key hits the default branch and returns this error wrapped with the InvalidFilter sentinel, meaning the filter parameter is unrecognized.

Source

Thrown at pkg/database/decisions.go:256

		case "scopes":
			decisions = decisions.Where(decision.ScopeEQ(value[0]))
		case "uuid":
			decisions = decisions.Where(decision.UUIDIn(value...))
		case "origin":
			decisions = decisions.Where(decision.OriginEQ(value[0]))
		case "value":
			decisions = decisions.Where(decision.ValueEQ(value[0]))
		case "type":
			decisions = decisions.Where(decision.TypeEQ(value[0]))
		case "ip", "range":
			rng, err = csnet.NewRange(value[0])
			if err != nil {
				return 0, nil, fmt.Errorf("unable to convert '%s' to int: %w: %w", value[0], err, InvalidIPOrRange)
			}
		case "scenario":
			decisions = decisions.Where(decision.ScenarioEQ(value[0]))
		default:
			return 0, nil, fmt.Errorf("'%s' doesn't exist: %w", param, InvalidFilter)
		}
	}

	decisions, err = decisionIPFilter(decisions, contains, rng)
	if err != nil {
		return 0, nil, err
	}

	decisionsToDelete, err := decisions.All(ctx)
	if err != nil {
		c.Log.Warningf("ExpireDecisionsWithFilter : %s", err)
		return 0, nil, fmt.Errorf("expire decisions with provided filter: %w", DeleteFail)
	}

	count, err := c.ExpireDecisions(ctx, decisionsToDelete)
	if err != nil {
		return 0, nil, fmt.Errorf("expire decisions with provided filter: %w: %w", err, DeleteFail)
	}

View on GitHub (pinned to 909b515798)

Solutions

  1. Use one of the supported keys: contains, scopes, uuid, origin, value, type, ip, range, scenario
  2. Fix misspellings (scopes not scope, scenario not scenarios)
  3. Check errors.Is(err, database.InvalidFilter) to return a 400 to API callers

Example fix

// before
c.ExpireDecisionsWithFilter(ctx, map[string][]string{"scope": {"ban"}})
// after
c.ExpireDecisionsWithFilter(ctx, map[string][]string{"scopes": {"ban"}})
Defensive patterns

Strategy: validation

Validate before calling

var validFilterKeys = map[string]bool{
    "contains": true, "scopes": true, "uuid": true, "origin": true,
    "value": true, "type": true, "ip": true, "range": true, "scenario": true,
}
for k := range filter {
    if !validFilterKeys[k] { return fmt.Errorf("unsupported filter key %q", k) }
}

Try / catch

if _, _, err := client.ExpireDecisionsWithFilter(ctx, filter); err != nil {
    if errors.Is(err, database.InvalidFilter) {
        return fmt.Errorf("unknown filter parameter: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Passing a misspelled or unsupported key in the filter map, e.g. "scope" instead of "scopes", "values", or "origin_" when calling ExpireDecisionsWithFilter / DeleteDecisions / DecisionCmd.

Common situations: API clients guessing filter key names; refactors renaming keys on one side only; scripts translated from v1 decisions API which used different parameter names.

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