libnyanpasu/clash-nyanpasu · warning

remove path `{dotted}` on non-mapping item, skipped

Error message

remove path `{dotted}` on non-mapping item, skipped

What it means

The `remove` action's string path entries only apply to mapping items; when the current item is not an object, the executor skips that path with a warning (legacy merge behavior applied only to mappings).

Source

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

            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!(
                        "remove path `{dotted}` on non-mapping item, skipped"
                    )));
                    continue;
                }
                let segments = parse_dotted_path(dotted);
                match remove_at(&current, &segments) {
                    Some(next) => current = next,
                    None => logs.push(StepLogEntry::warn(format!(
                        "remove path `{dotted}` not found, skipped"
                    ))),
                }
            }
            ConfigValue::Number(index) => {
                // Legacy numeric removal applies to sequence items only
                // (merge.rs:221 `Value::Sequence(list) if key.is_i64()`).
                if !matches!(current, ConfigValue::Array(_)) {
                    logs.push(StepLogEntry::warn(
                        "remove index on non-sequence item, skipped",

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Scope the `when` predicate so only mapping items reach the remove action
  2. Use a numeric index entry for sequence items instead of a dotted string path
  3. Restructure the list so items to be removed from are mappings
  4. Verify with logs which items are non-mapping and adjust the filter

Example fix

// before
when: "true"
remove: ["udp"]
// after
when: "item.name != null"
remove: ["udp"]
Defensive patterns

Strategy: type-guard

Validate before calling

// in `when`: only let mapping items reach string-path removals
// when: "item.name != null"

Type guard

fn item_is_mapping(v: &ConfigValue) -> bool { v.as_object_arc().is_some() }

Prevention

When it happens

Trigger: A filter `remove: ["some.path"]` entry is evaluated against a sequence item that is an array or scalar.

Common situations: Mixed-type lists (rules as strings) being filtered with path-based removal; assuming remove works uniformly across item types.

Related errors


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