{"record":{"id":"8999091ed1f57492","repo":"libnyanpasu/clash-nyanpasu","slug":"merge-value-for-field-is-not-a-sequence-skipp","errorCode":null,"errorMessage":"merge value for `{field}` is not a sequence, skipped","messagePattern":"merge value for `(.+?)` is not a sequence, skipped","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"backend/nyanpasu-config/src/runtime/executor/overlay.rs","lineNumber":60,"sourceCode":"            config = bare_key_merge(config, key, value);\n        }\n    }\n    config\n}\n\nfn strip_any<'a>(key: &'a str, prefixes: &[&str]) -> Option<&'a str> {\n    prefixes.iter().find_map(|prefix| key.strip_prefix(prefix))\n}\n\nfn splice_sequence(\n    config: ConfigValue,\n    field: &str,\n    value: &ConfigValue,\n    prepend: bool,\n    logs: &mut Vec<StepLogEntry>,\n) -> ConfigValue {\n    let Some(to_merge) = value.as_array_arc() else {\n        logs.push(StepLogEntry::warn(format!(\n            \"merge value for `{field}` is not a sequence, skipped\"\n        )));\n        return config;\n    };\n    let segments = parse_dotted_path(field);\n    let Some(target) = get_at(&config, &segments) else {\n        logs.push(StepLogEntry::warn(format!(\n            \"field `{field}` not found, skipped\"\n        )));\n        return config;\n    };\n    let Some(existing) = target.as_array_arc() else {\n        logs.push(StepLogEntry::warn(format!(\n            \"field `{field}` is not a sequence, skipped\"\n        )));\n        return config;\n    };\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/nyanpasu-config/src/runtime/executor/overlay.rs#L42-L78","documentation":"In splice_sequence, the merge value supplied for a field must be an array (items to prepend/append to the target field). If the overlay's merge value is not a sequence, the field is left untouched and a warning is logged.","triggerScenarios":"apply_overlay → splice_sequence: the overlay entry's value for `{field}` (with prepend/append merge) is a mapping or scalar instead of a list, so value.as_array_arc() returns None.","commonSituations":"Overlay rule like `rules: {prepend: MATCH,DIRECT}` where the value is a string instead of a list; writing `prepend: {...}` with an object; copy-pasting a single rule without wrapping it in a list.","solutions":["Wrap the merge value in a YAML/JSON list, even for a single item","Validate overlay merge values are arrays before applying","Check the field name in the warning to locate the offending overlay entry","Use `set`/override semantics instead of prepend/append if a scalar value is intended"],"exampleFix":"# before\nrules:\n  prepend: MATCH,DIRECT\n# after\nrules:\n  prepend:\n    - MATCH,DIRECT","handlingStrategy":"validation","validationCode":"fn merge_values_are_arrays(overlay: &ConfigValue) -> bool {\n    overlay.as_object_arc().map_or(false, |m| m.iter().all(|(_, v)|\n        v.get(\"prepend\").map_or(true, |x| x.as_array_arc().is_some()) &&\n        v.get(\"append\").map_or(true, |x| x.as_array_arc().is_some())))\n}","typeGuard":null,"tryCatchPattern":"let Some(to_merge) = value.as_array_arc() else {\n    return Err(anyhow!(\"merge value for `{field}` must be a sequence\"));\n};","preventionTips":["Always wrap merge values in a list, even for a single item","Use override/set semantics for scalar values instead of prepend/append","Lint overlay documents for non-array prepend/append values"],"tags":["config","overlay","merge","schema"],"backgroundTag":"config-type-mismatch","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}