dbt-labs/dbt-core · warning
warning should retain its FsError
Error message
warning should retain its FsError
What it means
This is a test assert in dbt-parser's macro-resolution tests: it panics with "warning should retain its FsError" when a warning emitted during markdown doc parsing fails to downcast its log attributes to FsErrorLog. The parser contract requires filesystem warnings to carry the structured FsError payload so callers can inspect error codes and locations; the test guards that contract.
Source
Thrown at crates/dbt-parser/src/resolve/resolve_macros.rs:752
let previous_record_count = log_records.lock().unwrap().len();
let _ = resolve_docs_macros(&io_args, &assets, None)?;
let records = log_records.lock().unwrap();
let warnings = &records[previous_record_count..];
assert_eq!(
warnings.len(),
case.expected_warning_paths.len(),
"expected one warning for case {}",
case.name
);
for (warning, expected_path) in
warnings.iter().zip(case.expected_warning_paths.iter())
{
assert_eq!(warning.severity_number, SeverityNumber::Warn);
let warning = warning
.attributes
.downcast_ref::<FsErrorLog>()
.expect("warning should retain its FsError");
assert_eq!(warning.get_fs_error().code, case.expected_code);
assert_eq!(
warning
.get_fs_error()
.location
.as_ref()
.map(|loc| loc.file.as_ref().clone()),
Some(PathBuf::from(expected_path)),
"expected warning location for case {}",
case.name
);
}
}
// Positive case
let valid_path = PathBuf::from("models/valid_doc.md");
fs::write(
base_path.join(&valid_path),View on GitHub (pinned to 0267ce9170)
Solutions
- Locate the warning emission for invalid markdown docs in resolve_macros.rs and ensure it attaches FsErrorLog (with correct code and location) to the log attributes.
- Check that FsErrorLog still implements the expected attributes trait (e.g., via extend_as_attributes) and was not changed to a plain string.
- Re-run the single test with `cargo test -p dbt-parser invalid_markdown_doc` after the fix.
Example fix
// before
warn!("invalid markdown doc: {}", err);
// after
warn!(error = %FsErrorLog::new(err.clone()), "invalid markdown doc"); Defensive patterns
Strategy: type-guard
Validate before calling
// before asserting, check the attribute type
if warning.attributes.downcast_ref::<FsErrorLog>().is_none() {
panic!("warning missing FsErrorLog payload: {:?}", warning.attributes);
} Type guard
fn as_fs_error_log(attrs: &dyn std::any::Any) -> Option<&FsErrorLog> { attrs.downcast_ref::<FsErrorLog>() } Try / catch
// Rust panics abort the test; catch in integration harnesses with catch_unwind let result = std::panic::catch_unwind(|| run_parse_with_warnings());
Prevention
- Always emit filesystem warnings through FsErrorLog so the payload survives
- Add a unit test asserting FsErrorLog attachment for every warning site
- Avoid middleware that rewrites log attributes
When it happens
Trigger: Running invalid_markdown_doc_reports_warning_and_continues when resolve_macros emits a warning whose attributes do not contain an FsErrorLog (i.e., the warning path in resolve_macros.rs was changed to log via a plain message instead of FsErrorLog::new(...)).
Common situations: A contributor refactors warning emission in resolve_macros and swaps FsErrorLog for a generic log attribute; a middleware/telemetry layer strips or replaces the attributes map before the assertion runs.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- macro still present
- cannot consume EOF
- owner key in config.meta
- expected `exclude` sequence in serialized atom
- All snapshot macros should start with 'snapshot_'
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/8e34f163ddd33bb2.
Report an issue: GitHub.