dbt-labs/dbt-core · error
expected `exclude` sequence in serialized atom
Error message
expected `exclude` sequence in serialized atom
What it means
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.
Source
Thrown at crates/dbt-parser/src/resolve/resolve_selectors.rs:600
None,
None,
Some(dbt_common::node_selector::IndirectSelection::default()),
Some(Box::new(SelectExpression::Or(vec![
atom(MethodName::Tag, "usage"),
atom(MethodName::Tag, "feed_service_now"),
]))),
));
let yaml = select_expression_to_yaml(&expr);
assert_eq!(yaml.get("method").and_then(|v| v.as_str()), Some("fqn"));
assert_eq!(yaml.get("value").and_then(|v| v.as_str()), Some("*"));
// `exclude` must be a single-element list wrapping the union.
let exclude = yaml
.get("exclude")
.and_then(|v| v.as_sequence())
.expect("expected `exclude` sequence in serialized atom");
assert_eq!(exclude.len(), 1);
let union = exclude[0]
.get("union")
.and_then(|v| v.as_sequence())
.expect("expected `union` sequence inside exclude");
let mut tags: Vec<String> = union
.iter()
.map(|item| {
assert_eq!(item.get("method").and_then(|v| v.as_str()), Some("tag"));
item.get("value")
.and_then(|v| v.as_str())
.unwrap()
.to_string()
})
.collect();
tags.sort();
assert_eq!(tags, vec!["feed_service_now", "usage"]);View on GitHub (pinned to 0267ce9170)
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.
Example fix
// before
exclude: {union: [a, b]}
// after
exclude:
- union: [a, b] Defensive patterns
Strategy: type-guard
Validate before calling
// assert serialized shape before parsing in consumers
if !yaml.get("exclude").map_or(false, |v| v.is_sequence()) {
eprintln!("exclude is not a sequence: {:?}", yaml.get("exclude"));
} Type guard
fn exclude_is_sequence(yaml: &serde_yaml::Value) -> bool { yaml.get("exclude").map_or(false, |v| v.is_sequence()) } Prevention
- 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
When it happens
Trigger: The selector atom serializer changed shape — e.g., emitting `exclude: {union: [...]}` (a map) or omitting exclude — so `.as_sequence()` returns None in the test.
Common situations: A refactor of SelectorAtom serialization (serde attributes like flatten/untagged) altering the exclude representation; YAML tagged vs untagged union output change.
Related errors
- Failed to convert value to YAML: {err}
- invalid serialized time precision
- invalid serialized timestamp precision
- Failed to deserialize
- ok
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/c315b758777f424b.
Report an issue: GitHub.