libnyanpasu/clash-nyanpasu · warning · StepLogEntry

field `{field}` not found, skipped

Error message

field `{field}` not found, skipped

What it means

This is not a panic but a warning entry pushed into the overlay executor's step log: `override_path` failed to find the dotted path `field` in the config tree, so the override value was skipped. Legacy overlay semantics (matching merge.rs:292-304) intentionally do NOT create missing paths on override — the target key must already exist. The call still succeeds; the skip is recorded for diagnostics.

Source

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

            .cloned()
            .chain(to_merge.iter().cloned())
            .collect()
    };
    replace_at(&config, &segments, ConfigValue::Array(Arc::from(items))).unwrap_or(config)
}

fn override_path(
    config: ConfigValue,
    field: &str,
    value: &ConfigValue,
    logs: &mut Vec<StepLogEntry>,
) -> ConfigValue {
    let segments = parse_dotted_path(field);
    match replace_at(&config, &segments, value.clone()) {
        Some(next) => next,
        None => {
            // Legacy: override does NOT create missing paths (merge.rs:292-304).
            logs.push(StepLogEntry::warn(format!(
                "field `{field}` not found, skipped"
            )));
            config
        }
    }
}

/// Bare key: deep-merge for maps, wholesale replace otherwise, insert when
/// absent (merge.rs:8-24, 310-312). Original key case preserved.
fn bare_key_merge(config: ConfigValue, key: &Arc<str>, data: &ConfigValue) -> ConfigValue {
    let existing = config
        .as_object_arc()
        .and_then(|map| map.get(key.as_ref()))
        .cloned();
    let merged = deep_merge_value(existing.as_ref(), data);
    super::value_util::obj_insert(&config, key.as_ref(), merged)
}

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Check the dotted path spelling and that the parent chain exists in the target config.
  2. Use a `merge`/`set` step (which creates missing paths) instead of `override` when you intend to add new fields.
  3. Run the overlay with step-log inspection enabled and fix each reported 'field not found' key.
  4. Regenerate overlay files against the current config schema after app version upgrades.

Example fix

// before (field absent -> skipped)
override:
  verge.enable_tun_mode: true
// after (create the field explicitly via set/merge)
set:
  verge.enable_tun_mode: true
override:
  verge.existing_field: true
Defensive patterns

Strategy: validation

Validate before calling

fn field_exists(config: &ConfigValue, field: &str) -> bool {
    let segments = parse_dotted_path(field);
    let mut cur = config;
    for seg in &segments {
        match cur.get(seg) {
            Some(next) => cur = next,
            None => return false,
        }
    }
    true
}
// use: field_exists(&config, "verge.enable_tun_mode")

Try / catch

// inspect the step log returned by apply_overlay
for entry in result.log.iter().filter(|e| e.level == Warn) {
    if entry.message.contains("not found, skipped") {
        eprintln!("overlay skipped: {}", entry.message);
    }
}

Prevention

When it happens

Trigger: Calling `apply_overlay`/`override_path` with a patch key whose dotted path does not resolve in the current config, e.g. overriding `verge.some_new_field` when `verge.some_new_field` is absent, or any typo in a nested key name.

Common situations: Merge/patch files written for a newer config schema applied to an older config; typos in overlay YAML/JSON keys; profile enhance chains referencing fields removed after a config migration.

Related errors


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