dbt-labs/dbt-core · error
The 'statement' result named '{name}' has already been loade
Error message
The 'statement' result named '{name}' has already been loaded into a variable What it means
store_result saves the result of a {% set result %}/{% statement %} block into a shared result store keyed by name. If the stored value has already been consumed (it equals the 'none_value()' placeholder), loading it again is refused with MacroResultAlreadyLoadedError: each named statement result can be read into a variable only once. The name 'main' is exempt and can be re-read.
Source
Thrown at crates/dbt-adapter/src/load_store.rs:113
/// https://github.com/dbt-labs/dbt-core/blob/34bb3f94dde716a3f9c36481d2ead85c211075dd/core/dbt/context/providers.py#L1022
pub fn load_result(
&self,
) -> impl Fn(&[Value]) -> Result<Value, minijinja::Error> + Clone + use<> {
let store = self.clone();
move |args: &[Value]| {
// name: str,
let iter = ArgsIter::new("load_result", &["name"], args);
let name: String = iter.next_arg::<&str>()?.to_string();
iter.finish()?;
let mut results = store.results.lock().unwrap();
if let Some(value) = results.get_mut(&name) {
if name == "main" {
Ok(value.clone())
} else if *value == none_value() {
Err(minijinja::Error::new(
minijinja::ErrorKind::MacroResultAlreadyLoadedError,
format!(
"The 'statement' result named '{name}' has already been loaded into a variable"
),
))
} else {
let result = value.clone();
*value = none_value();
Ok(result)
}
} else {
Ok(none_value())
}
}
}
/// https://github.com/dbt-labs/dbt-core/blob/34bb3f94dde716a3f9c36481d2ead85c211075dd/core/dbt/context/providers.py#L1043
pub fn store_raw_result(View on GitHub (pinned to 0267ce9170)
Solutions
- Rename each statement/set-result block so every result has a unique name and is loaded only once.
- Assign the loaded value to a variable once and reuse the variable instead of calling load_result again.
- Use the reserved name 'main' only when re-reading is intended, since it bypasses the already-loaded check.
- Refactor shared macros to pass the result as an argument rather than re-fetching it from the store.
Example fix
// before
{% do load_result('stmt') %}
{% do load_result('stmt') %}
// after
{% set res = load_result('stmt') %}
{% do use(res) %} {# reuse the variable, do not re-load #} Defensive patterns
Strategy: try-catch
Validate before calling
{% set existing = context.get('loaded_results', {}).get('stmt') %}
{% if existing is none %}
{% set res = load_result('stmt') %}
{% else %}
{% set res = existing %}
{% endif %} Try / catch
match store.store_result(name, value) {
Ok(v) => v,
Err(e) if e.kind() == minijinja::ErrorKind::MacroResultAlreadyLoadedError => reuse_previously_loaded(name),
Err(e) => return Err(e),
} Prevention
- Give every statement/set result a unique name; never load_result the same name twice
- Cache the loaded value in a variable and pass it around instead of re-fetching
- Reserve the name 'main' for results that are intentionally re-readable
- Track loaded result names in macro-local state when composing multiple macros
When it happens
Trigger: A macro or template loads the same named statement result twice, e.g. calling load_result('foo') twice after a {% set foo %}...{% endset %} statement, or storing under a name that was already loaded (store_result called from CompileNodeCtx/ResolveCtx pipelines with duplicate result names).
Common situations: Reusing a result variable across two Jinja calls in one node's compilation; copy-pasted macros that both do load_result('stmt'); running a node whose compile and resolve contexts both store/load the same statement name; upgrading dbt where previously tolerated double-loads now error.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- describe_dynamic_table is not supported by the {} adapter
- describe_interactive_table is not supported by the {} adapte
- target is not set in state
- Documentation depends on doc '{doc_name}' which was not foun
- diff_of_two_dicts requires exactly 2 arguments
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/f6ab2effeb73085f.
Report an issue: GitHub.