dbt-labs/dbt-core · error · InvalidOperation
doc() takes one or two positional string arguments
Error message
doc() takes one or two positional string arguments
What it means
In strict mode, the Jinja doc() function accepts exactly one or two positional string arguments and no keyword arguments, mirroring dbt-core's doc(self, *args). When the argument count or kwargs violate this signature, this InvalidOperation error is raised at parse time of the call.
Source
Thrown at crates/dbt-jinja-utils/src/functions/base.rs:232
.first()
.map(|(_, idx)| self.docs_content[*idx].as_str())
})
}
}
impl Object for DocMacro {
/// Implements the call method on the var object
fn call(
self: &Arc<Self>,
state: &State<'_, '_>,
args: &[Value],
_listeners: &[Rc<dyn RenderingEventListener>],
) -> Result<Value, Error> {
let mut args = ArgParser::new(args, None);
// Core's `doc(self, *args: str)`. Lenient mode keeps the historical tolerance,
// because model/source/column descriptions still render through it.
if self.strict && (args.kwargs_len() != 0 || !(1..=2).contains(&args.positional_len())) {
return Err(Error::new(
ErrorKind::InvalidOperation,
"doc() takes one or two positional string arguments",
));
}
let (arg1, arg2) = if self.strict {
// Both args are annotated `str`, so no coercion either.
let package_or_name = args.get::<Arc<str>>("")?.to_string();
let name = if args.positional_len() == 0 {
None
} else {
Some(args.get::<Arc<str>>("")?.to_string())
};
(package_or_name, name)
} else {
let arg1 = args.get::<String>("").map_err(|_| {
Error::new(
ErrorKind::InvalidOperation,
"Invalid arguments to doc macro",View on GitHub (pinned to 0267ce9170)
Solutions
- Call doc() with exactly one argument: {{ doc('column_name') }}.
- Use two arguments only for package-qualified docs: {{ doc('package_name', 'doc_name') }}.
- Remove any keyword arguments from the doc() call.
- If legacy templates need lenient behavior, run with strict mode disabled.
Example fix
// before
{{ doc('orders', 'order_id', extra) }}
// after
{{ doc('orders', 'order_id') }} Defensive patterns
Strategy: validation
Validate before calling
{% if var_args | length > 2 %}{% do exceptions.raise_compiler_error('doc() takes at most 2 args') %}{% endif %} Try / catch
{% set result = doc(name, package) %} Prevention
- Use {{ doc('name') }} or {{ doc('package', 'name') }} forms only.
- Never pass keyword arguments to doc().
- Lint templates for doc( calls with more than one comma.
When it happens
Trigger: Invoking {{ doc(...) }} with zero, three or more positional arguments, or with any keyword arguments, while strict mode is enabled.
Common situations: Typo like {{ doc('a', 'b', 'c') }}, accidentally passing kwargs ({{ doc(name='x') }}), or a macro-generated call with extra args after migrating to strict rendering.
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
- Invalid arguments to doc macro
- role must be a string
- Documentation depends on doc '{doc_name}' which was not foun
- otel_trace_id() takes no arguments
- RelationConfigBaseObject does not support method: {}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/906bdf8c43dc73f9.
Report an issue: GitHub.