dbt-labs/dbt-core · error · minijinja::Error (UndefinedError)
adapter not found in context
Error message
adapter not found in context
What it means
Inside `submit_python_job`, the actual work is delegated to the `adapter` object looked up from the Jinja state. This `UndefinedError` is raised when no `adapter` is present in the current context, meaning the function was evaluated in a context where the adapter was never injected. The code comment notes this should only be reachable outside the run-node statement context, where the call would normally fail earlier as an unrecognized function.
Source
Thrown at crates/dbt-jinja-utils/src/phases/run/run_node_context.rs:819
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]
//
// In fusion, we shouldn't need to do this because this funciton is only registered in the run node context
// so if a user tries to use it outside of a statement.sql macro, in a materialization macro, it will fail earlier due to an unrecongized function call.
// Get adapter from context and call submit_python_job
let adapter = state
.lookup("adapter", &[])
.ok_or_else(|| Error::new(ErrorKind::UndefinedError, "adapter not found in context"))?;
adapter.call_method(
state,
"submit_python_job",
&[parsed_model.clone(), MinijinjaValue::from(compiled_code)],
&[],
)
}
}
View on GitHub (pinned to 0267ce9170)
Solutions
- Only call `submit_python_job` inside a run-node statement context (statement.sql for python models), not in materialization or other macros.
- Ensure the correct adapter is installed and selected so `adapter` is registered in the run node context.
- If hit in a custom macro, move the call into the model's compiled code/statement context instead.
Example fix
-- before (materialization macro)
{% do submit_python_job(model, code) %}
-- after (statement.sql context of a python model)
-- invoke via the standard python model execution path instead of calling it directly in a macro
Defensive patterns
Strategy: try-catch
Validate before calling
{# only call submit_python_job inside statement.sql / python model execution context #}
{% if 'adapter' not in context %}
{{ exceptions.raise_compiler_error('submit_python_job requires the run node adapter context') }}
{% endif %} Try / catch
match result {
Err(e) if e.to_string().contains("adapter not found in context") => {
// wrong phase/context: reroute the call into statement.sql execution
}
other => other,
} Prevention
- Only use submit_python_job in python model statement contexts, never in materialization macros.
- Verify the adapter plugin is installed so `adapter` is registered.
- Keep calls inside statement.sql rather than shared macros.
When it happens
Trigger: Calling `submit_python_job` in a context built without the adapter binding — e.g. during parse phases, in a macro evaluated outside `statement.sql`, or in a context where `extend_base_context_stateful_fn`/`build_run_node_overlay` did not register `adapter`.
Common situations: Using `submit_python_job` in dbt_docs or analysis contexts; invoking it from a materialization macro rather than statement.sql; running with an adapter plugin missing so the adapter binding was never registered.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- describe_dynamic_table is not supported by the {} adapter
- describe_interactive_table is not supported by the {} adapte
- invalid return value
- target is not set in state
- In adapter.dispatch, got a macro name of "{macro_name}", but
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/eba285db74ebdde3.
Report an issue: GitHub.