derailed/k9s · warning

invalid rx filter %q: %w

Error message

invalid rx filter %q: %w

What it means

TableData.rxFilter compiles the user's filter string as a case-insensitive regex ((?i)(q)) after stripping a leading '!' for inverse mode; multi-word queries are treated as plain text and skip regex. Any string that is not a valid Go regex (unbalanced parentheses, stray '*', trailing backslash, bad character class) fails regexp.Compile and is reported with the compile error wrapped.

Source

Thrown at internal/model1/table_data.go:176

		td.rowEvents = rr
	} else {
		slog.Error("RX filter failed", slogs.Error, err)
	}

	return td
}

func (t *TableData) rxFilter(q string, inverse bool) (*RowEvents, error) {
	if strings.Contains(q, " ") {
		return t.rowEvents, nil
	}

	if inverse {
		q = q[1:]
	}
	rx, err := regexp.Compile(`(?i)(` + q + `)`)
	if err != nil {
		return nil, fmt.Errorf("invalid rx filter %q: %w", q, err)
	}

	vidx := t.header.FilterColIndices(t.namespace, true)
	rr := NewRowEvents(t.RowCount() / 2)
	t.rowEvents.Range(func(_ int, re RowEvent) bool {
		ff := make([]string, 0, len(re.Row.Fields))
		for idx, r := range re.Row.Fields {
			if !vidx.Has(idx) {
				continue
			}
			ff = append(ff, r)
		}
		match := rx.MatchString(strings.Join(ff, spacer))
		if (inverse && !match) || (!inverse && match) {
			rr.Add(re)
		}

		return true

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Fix the regex: balance groups, escape metacharacters (\. \* \[ \( ) as literals
  2. RE2 has no lookaround/backreferences — replace (?=x) patterns with simpler alternations
  3. Add a space to force plain-text matching instead of regex (multi-word queries bypass regex)
  4. Test the pattern first: echo 'name' | grep -E '(?i)(your-pattern)' or use Go's regexp to validate

Example fix

# before: glob-style filter (invalid regex)
*.prod\

# after: escaped, valid regex
.*\.prod
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate the filter the same way the view does.
query := strings.TrimPrefix(q, "!") // inverse prefix is stripped first
if _, err := regexp.Compile("(?i)(" + query + ")"); err != nil {
    return fmt.Errorf("bad filter %q: %w — escape regex metacharacters or add a space for plain text", q, err)
}

Try / catch

events, err := td.rxFilter(q, inverse)
if err != nil && strings.Contains(err.Error(), "invalid rx filter") {
    // keep the session alive: revert to unfiltered view and show a hint
    ui.Flash().Errf("Invalid regex filter %q — see :help filter", q)
    return td.rowEvents, nil
}

Prevention

When it happens

Trigger: Typing a filter in a k9s list view containing regex metacharacters, e.g. 'my-app(', '500*', 'pod\', '[a-' — any invalid Go RE2 syntax. Queries with spaces never hit this (plain match); a leading '!' is removed before compiling so '!(' fails on the '(' alone.

Common situations: Copy-pasting strings with glob-style wildcards ('*.prod') or shell globs into the filter bar; assuming PCRE syntax (lookaheads like (?=...) are unsupported in RE2); trailing backslashes from partial typing.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/02a7c5c05199aac4. Report an issue: GitHub.