dbt-labs/dbt-core · error · minijinja::Error (InvalidOperation)

submit_python_job expects 2 arguments, got

Error message

submit_python_job expects 2 arguments, got {}

What it means

The `submit_python_job` Jinja context function registered in the run node overlay requires exactly two arguments: the parsed model object and the compiled Python code string. The library throws this arity error when the template calls `submit_python_job` with any other number of arguments. It is an eager API-contract check before any adapter work happens.

Solutions

  1. Call `submit_python_job(parsed_model, compiled_code)` with exactly two positional arguments.
  2. Remove any extra arguments (e.g. config dicts) — configuration belongs in the model config block, not this call.
  3. Check the macro that wraps the call to make sure it forwards exactly two values.

Example fix

-- before
{% do submit_python_job(model, compiled_code, config) %}
-- after
{% do submit_python_job(model, compiled_code) %}
Defensive patterns

Strategy: validation

Validate before calling

-- Jinja pre-check before the call
{% if var_args | length != 2 %}
  {{ exceptions.raise_compiler_error('submit_python_job needs exactly (model, compiled_code)') }}
{% endif %}

Prevention

When it happens

Trigger: A Jinja template calls `submit_python_job(model)` (missing compiled code), `submit_python_job()` with no args, or with three-plus args, e.g. passing an extra config object.

Common situations: Hand-written Python model materialization macros copied from older dbt versions with a different signature; typos like `submit_python_job(model, code, config)`; macros refactored to pass keyword-style extra params.

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/147c35a61d5f6b04. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-jinja-utils/src/phases/run/run_node_context.rs:794

        ));
    }

    match fs::write(full_path, payload) {
        Ok(_) => Ok(()),
        Err(e) => Err(Error::new(
            ErrorKind::InvalidOperation,
            format!("Failed to write to {}: {}", full_path.display(), e),
        )),
    }
}

/// Returns the function used for the submit_python_job context.
fn submit_python_job_context_fn()
-> impl Fn(&State, &[MinijinjaValue]) -> Result<MinijinjaValue, Error> + Copy {
    |state: &State, args: &[MinijinjaValue]| {
        // Parse arguments: submit_python_job(parsed_model, compiled_code)
        if args.len() != 2 {
            return Err(Error::new(
                ErrorKind::InvalidOperation,
                format!("submit_python_job expects 2 arguments, got {}", args.len()),
            ));
        }
        let parsed_model = &args[0];
        let compiled_code = args[1].as_str().ok_or_else(|| {
            Error::new(
                ErrorKind::InvalidOperation,
                "compiled_code must be a string",
            )
        })?;

        // Note(Ani):
        // dbt-core validates:
        //   - macro_stack.depth == 2
        //   - call_stack[1] == "macro.dbt.statement"
        //   - "materialization" in call_stack[0]
        //

View on GitHub (pinned to 0267ce9170)