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

  1. Call doc() with exactly one argument: {{ doc('column_name') }}.
  2. Use two arguments only for package-qualified docs: {{ doc('package_name', 'doc_name') }}.
  3. Remove any keyword arguments from the doc() call.
  4. 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

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


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/906bdf8c43dc73f9. Report an issue: GitHub.