dbt-labs/dbt-core · error · minijinja::Error::InvalidOperation
project in a GrantAccessToTarget cannot be empty
Error message
project in a GrantAccessToTarget cannot be empty
What it means
After successfully deserializing GrantAccessToTarget, grant_access_to() requires a non-empty `project` because BigQuery authorized views/grants are granted across projects. If grant_target.project is absent or None, this InvalidOperation error is raised stating that project cannot be empty.
Solutions
- Add the `project` key with the target GCP project id to the grant target dict.
- Verify the model's grants configuration supplies the full target ({project, dataset}).
- If the target is in the same project, still pass its explicit project id rather than omitting it.
- Update custom grant macros to require and forward the project field.
Example fix
// before
{% do adapter.grant_access_to(entity, 'view', 'viewer', {'dataset': 'shared_data'}) %}
// after
{% do adapter.grant_access_to(entity, 'view', 'viewer', {'project': 'my-gcp-project', 'dataset': 'shared_data'}) %} Defensive patterns
Strategy: validation
Validate before calling
{% if grant_target.get('project') is defined and grant_target.get('project') is not none %}
{% do adapter.grant_access_to(entity, 'view', 'viewer', grant_target) %}
{% else %}
{{ exceptions.raise_compiler_error("grant target requires a non-empty project") }}
{% endif %} Prevention
- Always include project in grant target dicts, even within the same GCP project
- Check grant configuration completeness before running grants
- Add assertions in custom grant macros for required fields
When it happens
Trigger: adapter.grant_access_to(entity, entity_type, role, {'dataset': 'analytics'}) — the dict deserializes (project is optional in the struct) but is missing the project key, or project is explicitly null, when granting access to a target in another project.
Common situations: Authorized-view setups in BigQuery where the shared dataset lives in a different GCP project and users omit `project` assuming it defaults to the target's project; templates migrated from Python dbt where None project was tolerated differently.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- dataset in a GrantAccessToTarget cannot be empty
- adapter.add_time_ingestion_partition_column failed on…
- adapter.parse_partition_by failed on
- An unexpected error occurred during package installation
- 'api_endpoint' is missing a trailing '/', which dbt appends…
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/67f553d2a8b3f35d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/dbt-adapter/src/adapter/mod.rs:2296
args,
);
let entity_val = iter.next_arg::<&Value>()?;
let entity_type = iter.next_arg::<&str>()?;
let role_val = iter.next_arg::<&Value>()?;
let grant_target_dict = iter.next_arg::<&Value>()?;
let grant_target = minijinja_value_to_typed_struct::<GrantAccessToTarget>(
grant_target_dict.clone(),
)
.map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::SerdeDeserializeError,
e.to_string(),
)
})?;
iter.finish()?;
let database = grant_target.project.as_deref().ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"project in a GrantAccessToTarget cannot be empty",
)
})?;
let schema = grant_target.dataset.as_deref().ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"dataset in a GrantAccessToTarget cannot be empty",
)
})?;
let role = if role_val.is_none() || role_val.is_undefined() {
None
} else {
Some(role_val.as_str().ok_or_else(|| {
minijinja::Error::new(
minijinja::ErrorKind::InvalidOperation,
"role must be a string",View on GitHub (pinned to 0267ce9170)