dbt-labs/dbt-core · error · minijinja::Error (InvalidOperation)
argument 'name' to has_var() has incompatible type; value is
Error message
argument 'name' to has_var() has incompatible type; value is not a string
What it means
Type guard in DbtJinjaVars::call_has_var: the first positional argument to has_var() must be a variable name, but the supplied Jinja value is not a string, so it cannot name a var to look up. The at-fault input is the argument passed to has_var() in the template.
Source
Thrown at crates/dbt-jinja-vars/src/var.rs:121
format!(
"Required var '{}' not found in config:\nVars supplied to {} = {}",
var_name,
package_name,
serde_json::to_string_pretty(vars_lookup).unwrap()
),
)
}
/// Common handler for `has_var`.
fn call_has_var(&self, state: &State<'_, '_>, args: &[Value]) -> Result<Value, Error> {
if args.is_empty() {
return Err(Error::new(
ErrorKind::InvalidOperation,
"has_var requires 1 argument",
));
}
let var_name = args[0].as_str().ok_or_else(|| {
Error::new(
ErrorKind::InvalidOperation,
"argument 'name' to has_var() has incompatible type; value is not a string",
)
})?;
let present = self.contains_var(state, var_name)?;
Ok(Value::from(present))
}
/// Common implementation for `Object::call`.
fn call_impl(
self: &Arc<Self>,
state: &State<'_, '_>,
args: &[Value],
_listeners: &[Rc<dyn RenderingEventListener>],
) -> Result<Value, Error> {
let (var_name, default_value) = Self::parse_args(args)?;
self.call_as_function(state, var_name, default_value)
}View on GitHub (pinned to 0267ce9170)
Solutions
- Quote the name: `has_var('my_var')`.
- Coerce dynamic names with the `| string` filter: `has_var(key | string)`.
- Ensure you pass the lookup key, not the value you expect it to hold.
Example fix
// before (Jinja)
{% if has_var(warehouse_id) %}
// after
{% if has_var('warehouse_id') %} Defensive patterns
Strategy: type-guard
Validate before calling
{% if candidate is not string %}{{ exceptions.raise_compiler_error('has_var name must be a string') }}{% endif %} Type guard
// Jinja
{% macro safe_has_var(name) %}
{% if name is not string %}{{ return(false) }}{% endif %}
{{ return(has_var(name | string)) }}
{% endmacro %} Prevention
- Pass quoted literal names: has_var('name')
- Coerce dynamic names with | string before calling
- Do not confuse the var name (key) with its value
When it happens
Trigger: Calling `{{ has_var(42) }}`, `{{ has_var(some_var_value) }}` where the value is not a string, or passing a dict/list of candidate names.
Common situations: Passing the var's value instead of its name (confusing `has_var(my_var)` with checking the value); numeric column names used as var keys; dynamically built names not coerced to strings.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- argument 'name' to var() has incompatible type; value is not
- has_var requires 1 argument
- describe_dynamic_table is not supported by the {} adapter
- describe_interactive_table is not supported by the {} adapte
- The 'statement' result named '{name}' has already been loade
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/e7d9cee5e223ef18.
Report an issue: GitHub.