libnyanpasu/clash-nyanpasu · warning

invalid filter: no action

Error message

invalid filter: no action

What it means

apply_filter parsed a valid object filter with a `when` predicate, but none of the recognized action keys (override, merge, remove) were present, so no action can run. It warns and returns the items unfiltered.

Source

Thrown at backend/nyanpasu-config/src/runtime/executor/overlay.rs:201

            enum FilterAction<'a> {
                Expr(&'a str),
                Override(&'a ConfigValue),
                Merge(&'a ConfigValue),
                Remove(&'a Arc<[ConfigValue]>),
            }
            let action = if let Some(ConfigValue::String(expr)) = actions.get("expr") {
                FilterAction::Expr(expr.as_ref())
            } else if let Some(replacement) = actions.get("override") {
                FilterAction::Override(replacement)
            } else if let Some(merge) = actions
                .get("merge")
                .filter(|value| value.as_object_arc().is_some())
            {
                FilterAction::Merge(merge)
            } else if let Some(ConfigValue::Array(paths)) = actions.get("remove") {
                FilterAction::Remove(paths)
            } else {
                logs.push(StepLogEntry::warn("invalid filter: no action"));
                return items;
            };
            items
                .into_iter()
                .map(|item| {
                    let hit = match runner.eval_item_predicate(when, &item) {
                        Ok(hit) => hit,
                        Err(error) => {
                            logs.push(StepLogEntry::warn(format!(
                                "filter `when` failed, treated as false: {error}"
                            )));
                            false
                        }
                    };
                    if !hit {
                        return item;
                    }
                    match &action {

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Add one of the supported action keys: `override` (any value), `merge` (mapping), or `remove` (array of paths)
  2. Fix typos in the action key name
  3. Ensure `remove` is an array, not a string
  4. Cross-check the filter schema in the overlay docs

Example fix

// before
filter:
  when: "item.name == 'A'"
  removes:
    - udp
// after
filter:
  when: "item.name == 'A'"
  remove:
    - udp
Defensive patterns

Strategy: validation

Validate before calling

if let ConfigValue::Object(actions) = &filter {
    let has_action = actions.contains_key("override")
        || matches!(actions.get("merge"), Some(ConfigValue::Object(_)))
        || matches!(actions.get("remove"), Some(ConfigValue::Array(_)));
    assert!(has_action, "filter must define override, merge, or remove");
}

Type guard

fn filter_has_action(f: &ConfigValue) -> bool {
    matches!(f, ConfigValue::Object(a) if a.contains_key("override") || a.contains_key("merge") || a.contains_key("remove"))
}

Prevention

When it happens

Trigger: A filter object has `when` but its action key is misspelled or missing (e.g. `merges`, `del`, `override` holding a non-object value, `remove` not being an array).

Common situations: Typos in action names; `remove` written as a string instead of an array of paths; copy-pasted filter snippets from older schema versions.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/78eaa730fc90e648. Report an issue: GitHub.