libnyanpasu/clash-nyanpasu · warning · StepLogEntry
filter `expr` failed, item kept: {error}
Error message
filter `expr` failed, item kept: {error} What it means
During overlay filter application, the `expr` transform (FilterAction::Expr) failed to evaluate for an item. Unlike the `when` failure, the item is KEPT unchanged and a warning is logged. This fail-open behavior means a broken expression leaves the original item in the config rather than dropping it.
Source
Thrown at backend/nyanpasu-config/src/runtime/executor/overlay.rs:223
.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 {
FilterAction::Expr(expr) => match runner.eval_item_expr(expr, &item) {
Ok(next) => next,
Err(error) => {
logs.push(StepLogEntry::warn(format!(
"filter `expr` failed, item kept: {error}"
)));
item
}
},
FilterAction::Override(replacement) => (*replacement).clone(),
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)
}View on GitHub (pinned to f7dbce2997)
Solutions
- Fix the `expr` expression in the overlay filter rule (inspect the interpolated {error} in the warning log)
- Confirm every field the expression reads exists on all filtered items
- If the expression should replace the item wholesale and failure is unacceptable, validate the expression before applying the overlay
- Use FilterAction::Override instead of Expr if the value is static and needs no evaluation
Example fix
// before
{"expr": "item.name = 'x'"}
// after (correct assignment/transform syntax)
{"expr": "item.name := 'x'"} Defensive patterns
Strategy: validation
Validate before calling
fn valid_expr(expr: &str, sample: &ConfigValue) -> bool { ScriptRunner::default().eval_item_expr(expr, sample).is_ok() } Try / catch
match runner.eval_item_expr(expr, &item) { Ok(next) => next, Err(e) => { log::warn!("expr failed: {e}"); item } } Prevention
- Validate `expr` transforms against a sample item before applying overlays
- Keep expressions schema-version-aware; update them when item fields change
- Prefer FilterAction::Override for static values that need no evaluation
When it happens
Trigger: apply_filter calls runner.eval_item_expr(expr, &item) for a FilterAction::Expr rule and the script runner returns Err — syntax errors, references to non-existent item fields, or runtime exceptions inside the expression.
Common situations: A rewrite expression written for a prior schema (field renamed/removed); an expression with a typo or wrong return type; items with heterogeneous shapes where some lack the fields the expression mutates.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- filter `when` failed, treated as false: {error}
- filter expr failed, item removed: {error}
- field `{field}` not found, skipped
- overlay document is not a mapping, skipped
- merge value for `{field}` is not a sequence, skipped
AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08).
Data as JSON: /api/errors/cde3d676e1891907.
Report an issue: GitHub.