dbt-labs/dbt-core · error · InvalidOperation
Failed to convert value to YAML: {err}
Error message
Failed to convert value to YAML: {err} What it means
The toyaml Jinja filter first converts its input Minijinja Value into a serde_json::Value as an intermediate representation. If that conversion fails, this InvalidOperation error is raised (the message says YAML but the failure is in the JSON conversion step).
Source
Thrown at crates/dbt-jinja-utils/src/functions/base.rs:577
let sort_keys = iter
.next_kwarg::<Option<bool>>("sort_keys")?
.unwrap_or(false);
// If the value is undefined or none and there's a default, return it
if value.is_undefined() || value.is_none() {
return match default {
Some(def) => Ok(def.clone()),
// Return none for undefined/none values when no default is provided
None => Ok(Value::from(())),
};
}
// Convert the Minijinja Value to a serde_json::Value
// Should this say YAML or JSON cause this is toyaml function, not sure
let mut json_value = match serde_json::to_value(value) {
Ok(val) => val,
Err(err) => {
return Err(Error::new(
ErrorKind::InvalidOperation,
format!("Failed to convert value to YAML: {err}"),
));
}
};
// Sort keys if requested
if sort_keys && let Some(obj) = json_value.as_object_mut() {
let sorted_map: BTreeMap<_, _> = obj.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
*obj = sorted_map.into_iter().collect();
}
match dbt_yaml::to_string(&json_value) {
Ok(yaml_str) => Ok(Value::from(yaml_str)),
Err(err) => Err(Error::new(
ErrorKind::InvalidOperation,
format!("Failed to convert value to YAML: {err}"),
)),View on GitHub (pinned to 0267ce9170)
Solutions
- Ensure the input is plain data (mappings, sequences, scalars) before piping to toyaml.
- Guard the variable with is defined / is mapping before conversion.
- Serialize only plain attributes of complex objects.
- Read the inner err message to identify which value component failed conversion.
Example fix
// before
{{ undefined_var | toyaml }}
// after
{% if undefined_var is defined %}{{ undefined_var | toyaml }}{% endif %} Defensive patterns
Strategy: validation
Validate before calling
{% if value is not defined %}{% do exceptions.raise_compiler_error('toyaml input undefined') %}{% endif %} Try / catch
{% if value is defined and value is mapping %}{{ value | toyaml }}{% else %}{}{% endif %} Prevention
- Pipe only mappings/sequences/scalars into toyaml.
- Guard with is defined / is mapping before rendering.
- Do not serialize dbt objects (relations, macros) directly.
When it happens
Trigger: {{ value | toyaml }} where the Minijinja value cannot be converted to a serde_json value (unsupported/opaque types, cyclic or non-representable structures).
Common situations: Piping undefined variables or objects (e.g. relations, macros results) into toyaml; templates expecting implicit coercion of exotic types.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to serialize merged node config to dbt_yaml::Value fo
- get_csv_data: failed to format CSV: {e}
- {}
- Failed to convert value to JSON: {err}
- Contract Error for {} from {}: {}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/1a28f47e296f34ea.
Report an issue: GitHub.