dbt-labs/dbt-core · error · InvalidOperation
diff_of_two_dicts requires exactly 2 arguments
Error message
diff_of_two_dicts requires exactly 2 arguments
What it means
diff_of_two_dicts is a dbt Jinja helper (mirroring dbt-core's base.py) that returns the difference between two dictionaries. The Rust implementation requires exactly two positional arguments (or the dict_a/dict_b kwargs); if the argument count is anything other than 2 it throws this InvalidOperation error instead of proceeding. This is an argument-arity guard implemented by the library itself.
Source
Thrown at crates/dbt-jinja-utils/src/functions/base.rs:604
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}"),
)),
}
}
/// A function that returns the difference between two dictionaries
/// Not documented in dbt Jinja docs, but included in base.py
pub fn diff_of_two_dicts_fn() -> impl Fn(&[Value], Kwargs) -> Result<Value, Error> {
move |args: &[Value], kwargs: Kwargs| -> Result<Value, Error> {
if args.len() != 2 {
return Err(Error::new(
ErrorKind::InvalidOperation,
"diff_of_two_dicts requires exactly 2 arguments",
));
}
let dict_a_arg = match (kwargs.get("dict_a"), args.first()) {
(Ok(value), _) => value,
(_, Some(value)) => value,
_ => {
return Err(Error::new(
ErrorKind::InvalidOperation,
"diff_of_two_dicts requires a dict_a argument",
));
}
}
.clone();
let dict_b_arg = match (kwargs.get("dict_b"), args.get(1)) {View on GitHub (pinned to 0267ce9170)
Solutions
- Pass exactly two dict arguments: diff_of_two_dicts(dict_a, dict_b)
- If one dict may be missing, guard with an if-block or pass an empty dict {} instead of omitting the argument
- If using kwargs, supply both dict_a= and dict_b= together
Example fix
// before
{% set diff = diff_of_two_dicts(my_dict) %}
// after
{% set diff = diff_of_two_dicts(my_dict, other_dict) %} Defensive patterns
Strategy: validation
Validate before calling
{% if dict_a is not defined or dict_b is not defined %}
{{ exceptions.raise_compiler_error('diff_of_two_dicts needs both dicts in ' ~ this) }}
{% endif %} Type guard
{% macro has_both_dicts(a, b) %}
{{ return(a is defined and b is defined and a is mapping and b is mapping) }}
{% endmacro %} Prevention
- Always call diff_of_two_dicts with exactly two dict arguments
- Count arguments when building calls dynamically in loops
- Prefer kwarg form dict_a=/dict_b= to make omission visible
When it happens
Trigger: Calling diff_of_two_dicts(a) with one dict, diff_of_two_dicts() with none, or diff_of_two_dicts(a, b, c) with three or more arguments. Any Jinja template in a dbt model/macro that passes the wrong number of positional args.
Common situations: Template refactors where a second dict argument was dropped or an extra one added; conditional template logic that supplies args dynamically and sometimes passes only one; misunderstanding that the function needs both dicts in a single call rather than one per call.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- set() requires 1 argument
- render requires exactly one argument (the string to render)
- set_strict requires exactly 1 argument
- zip requires at least 1 argument
- has_var requires 1 argument
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/782b752ecb939e00.
Report an issue: GitHub.