-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Open
Labels
Description
Is this a new bug in dbt-core?
- I believe this is a new bug in dbt-core
- I have searched the existing issues, and I could not find an existing issue for this bug
Current Behavior
Bug Location
File: core/dbt/parser/manifest.py (or similar manifest building file)
Method: inject_external_nodes()
The Problem:
- Plugin nodes are correctly added to manifest.nodes via add_node_nofile()
- RefableLookup.populate() only runs once during initial manifest building
- Plugin nodes are injected after RefableLookup is built
- Missing: RefableLookup is never updated with plugin nodes
- Two-parameter ref() calls use RefableLookup exclusively → fail to find plugin nodes
Expected Behavior
Two-parameter ref() syntax should work correctly for plugin-injected models, just like it does for regular dbt package dependencies.
-- This should work without errors
SELECT * FROM {{ ref('external_package', 'external_model') }}
Steps To Reproduce
- in dbt 1.9 install dbt-loom
# Install dbt-loom (or any plugin that injects models)
pip install dbt-loom
# Configure the plugin
# dbt_loom.config.yml
manifests:
- name: external_project
type: file
config:
path: /path/to/external/target/manifest.json
optional: false
- Create Test Model
-- models/test_plugin_ref.sql
SELECT *
FROM {{ ref('external_project', 'some_external_model') }}
- Attempt to Parse/Compile
- Observe the Error
Compilation Error in model test_plugin_ref (models/test_plugin_ref.sql)
Model 'model.your_project.test_plugin_ref' depends on a node named 'external_project' which was not found
5: Verify Single-Parameter Works
-- Change the model to use single-parameter ref
SELECT *
FROM {{ ref('some_external_model') }}
Relevant log output
Environment
dbt-core version: 1.9.4
dbt-loom version: 0.9.1
dbt-snowflake version: 1.9.2
Python version: 3.9.15
OS: macOS 15.6.1
Which database adapter are you using with dbt?
No response
Additional Context
Proposed Fix - add one line to update RefableLookup after injecting plugin nodes:
def inject_external_nodes(self) -> bool:
# ... existing code ...
pm = plugins.get_plugin_manager(self.root_project.project_name)
plugin_model_nodes = pm.get_nodes().models
for node_arg in plugin_model_nodes.values():
node = ModelNode.from_args(node_arg)
if (
node.unique_id not in self.manifest.nodes
and node.unique_id not in self.manifest.disabled
):
self.manifest.add_node_nofile(node)
self.manifest.ref_lookup.add_node(node) # ← ADD THIS LINE
manifest_nodes_modified = True