libnyanpasu/clash-nyanpasu · warning

invalid filter value, skipped

Error message

invalid filter value, skipped

What it means

apply_filter only accepts filters that are arrays of predicates or objects with `when` plus an action. Any other filter value type (scalar like a number/bool, or malformed structure) is rejected with this warning and the items pass through unfiltered.

Source

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

                        FilterAction::Merge(merge) => {
                            // Legacy panics on non-mapping items (merge.rs:163
                            // `as_mapping_mut().unwrap()`); never-fail keeps
                            // the item instead (spec §13 #15).
                            if item.as_object_arc().is_none() {
                                logs.push(StepLogEntry::warn(
                                    "filter `merge` target item is not a mapping, item kept",
                                ));
                                return item;
                            }
                            deep_merge_value(Some(&item), merge)
                        }
                        FilterAction::Remove(paths) => remove_from_item(item, paths, logs),
                    }
                })
                .collect()
        }
        _ => {
            logs.push(StepLogEntry::warn("invalid filter value, skipped"));
            items
        }
    }
}

fn remove_from_item(
    item: ConfigValue,
    paths: &Arc<[ConfigValue]>,
    logs: &mut Vec<StepLogEntry>,
) -> ConfigValue {
    let mut current = item;
    for path in paths.iter() {
        match path {
            ConfigValue::String(dotted) => {
                // Legacy applies string paths to mapping items only
                // (merge.rs:186 `key.is_string() && item.is_mapping()`).
                if current.as_object_arc().is_none() {
                    logs.push(StepLogEntry::warn(format!(

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Wrap the predicate in a proper filter object: `{ when: "...", ...action }`
  2. Check YAML indentation so the filter parses as a mapping/array, not a scalar
  3. Quote strings only where expressions are expected (`when` values), not at the filter level
  4. Log and inspect the parsed filter value if unsure what shape it has

Example fix

// before (parses as a string)
filter: "item.name != 'DIRECT'"
// after
filter:
  when: "item.name != 'DIRECT'"
  remove: ["udp"]
Defensive patterns

Strategy: validation

Validate before calling

let valid = matches!(&filter, ConfigValue::Array(_))
    || matches!(&filter, ConfigValue::Object(a) if a.contains_key("when"));
assert!(valid, "filter must be an array of predicates or an object with `when`");

Type guard

fn is_valid_filter(v: &ConfigValue) -> bool {
    matches!(v, ConfigValue::Array(_)) || matches!(v, ConfigValue::Object(a) if a.contains_key("when"))
}

Prevention

When it happens

Trigger: An overlay filter step's `filter` value is a string, number, boolean, or other unrecognized shape.

Common situations: YAML quoting mistakes turning an intended object filter into a string; copy-paste of a predicate expression where a filter object is expected.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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