{"record":{"id":"c315b758777f424b","repo":"dbt-labs/dbt-core","slug":"expected-exclude-sequence-in-serialized-atom","errorCode":null,"errorMessage":"expected `exclude` sequence in serialized atom","messagePattern":"expected `exclude` sequence in serialized atom","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-parser/src/resolve/resolve_selectors.rs","lineNumber":600,"sourceCode":"            None,\n            None,\n            Some(dbt_common::node_selector::IndirectSelection::default()),\n            Some(Box::new(SelectExpression::Or(vec![\n                atom(MethodName::Tag, \"usage\"),\n                atom(MethodName::Tag, \"feed_service_now\"),\n            ]))),\n        ));\n\n        let yaml = select_expression_to_yaml(&expr);\n\n        assert_eq!(yaml.get(\"method\").and_then(|v| v.as_str()), Some(\"fqn\"));\n        assert_eq!(yaml.get(\"value\").and_then(|v| v.as_str()), Some(\"*\"));\n\n        // `exclude` must be a single-element list wrapping the union.\n        let exclude = yaml\n            .get(\"exclude\")\n            .and_then(|v| v.as_sequence())\n            .expect(\"expected `exclude` sequence in serialized atom\");\n        assert_eq!(exclude.len(), 1);\n\n        let union = exclude[0]\n            .get(\"union\")\n            .and_then(|v| v.as_sequence())\n            .expect(\"expected `union` sequence inside exclude\");\n        let mut tags: Vec<String> = union\n            .iter()\n            .map(|item| {\n                assert_eq!(item.get(\"method\").and_then(|v| v.as_str()), Some(\"tag\"));\n                item.get(\"value\")\n                    .and_then(|v| v.as_str())\n                    .unwrap()\n                    .to_string()\n            })\n            .collect();\n        tags.sort();\n        assert_eq!(tags, vec![\"feed_service_now\", \"usage\"]);","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-parser/src/resolve/resolve_selectors.rs#L582-L618","documentation":"Test assertion \"expected `exclude` sequence in serialized atom\" panics in test_serialize_atom_with_nested_exclude when the serialized YAML for a selection atom has an `exclude` key that is not a YAML sequence. The test verifies that a method/union selector with nested exclude serializes exclude as a single-element list wrapping the union.","triggerScenarios":"The selector atom serializer changed shape — e.g., emitting `exclude: {union: [...]}` (a map) or omitting exclude — so `.as_sequence()` returns None in the test.","commonSituations":"A refactor of SelectorAtom serialization (serde attributes like flatten/untagged) altering the exclude representation; YAML tagged vs untagged union output change.","solutions":["Print the serialized YAML in the test to inspect the actual exclude shape.","Fix the serializer so exclude emits as a sequence wrapping the nested union.","Update the test expectations only if the new serialization format is intentional."],"exampleFix":"// before\nexclude: {union: [a, b]}\n// after\nexclude:\n  - union: [a, b]","handlingStrategy":"type-guard","validationCode":"// assert serialized shape before parsing in consumers\nif !yaml.get(\"exclude\").map_or(false, |v| v.is_sequence()) {\n    eprintln!(\"exclude is not a sequence: {:?}\", yaml.get(\"exclude\"));\n}","typeGuard":"fn exclude_is_sequence(yaml: &serde_yaml::Value) -> bool { yaml.get(\"exclude\").map_or(false, |v| v.is_sequence()) }","tryCatchPattern":null,"preventionTips":["Add serde round-trip tests for SelectorAtom serialization","Avoid untagged/flatten serde attrs that change exclude's shape","Pin serializer format expectations in golden-file tests"],"tags":["rust","test-assertion","yaml","serialization"],"backgroundTag":"unexpected-response-shape","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}