{"record":{"id":"67f553d2a8b3f35d","repo":"dbt-labs/dbt-core","slug":"project-in-a-grantaccesstotarget-cannot-be-empty","errorCode":null,"errorMessage":"project in a GrantAccessToTarget cannot be empty","messagePattern":"project in a GrantAccessToTarget cannot be empty","errorType":"exception","errorClass":"minijinja::Error::InvalidOperation","httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/adapter/mod.rs","lineNumber":2296,"sourceCode":"                    args,\n                );\n                let entity_val = iter.next_arg::<&Value>()?;\n                let entity_type = iter.next_arg::<&str>()?;\n                let role_val = iter.next_arg::<&Value>()?;\n                let grant_target_dict = iter.next_arg::<&Value>()?;\n                let grant_target = minijinja_value_to_typed_struct::<GrantAccessToTarget>(\n                    grant_target_dict.clone(),\n                )\n                .map_err(|e| {\n                    minijinja::Error::new(\n                        minijinja::ErrorKind::SerdeDeserializeError,\n                        e.to_string(),\n                    )\n                })?;\n                iter.finish()?;\n\n                let database = grant_target.project.as_deref().ok_or_else(|| {\n                    minijinja::Error::new(\n                        minijinja::ErrorKind::InvalidOperation,\n                        \"project in a GrantAccessToTarget cannot be empty\",\n                    )\n                })?;\n                let schema = grant_target.dataset.as_deref().ok_or_else(|| {\n                    minijinja::Error::new(\n                        minijinja::ErrorKind::InvalidOperation,\n                        \"dataset in a GrantAccessToTarget cannot be empty\",\n                    )\n                })?;\n\n                let role = if role_val.is_none() || role_val.is_undefined() {\n                    None\n                } else {\n                    Some(role_val.as_str().ok_or_else(|| {\n                        minijinja::Error::new(\n                            minijinja::ErrorKind::InvalidOperation,\n                            \"role must be a string\",","sourceCodeStart":2278,"sourceCodeEnd":2314,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/adapter/mod.rs#L2278-L2314","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n{% do adapter.grant_access_to(entity, 'view', 'viewer', {'dataset': 'shared_data'}) %}\n\n// after\n{% do adapter.grant_access_to(entity, 'view', 'viewer', {'project': 'my-gcp-project', 'dataset': 'shared_data'}) %}","handlingStrategy":"validation","validationCode":"{% if grant_target.get('project') is defined and grant_target.get('project') is not none %}\n  {% do adapter.grant_access_to(entity, 'view', 'viewer', grant_target) %}\n{% else %}\n  {{ exceptions.raise_compiler_error(\"grant target requires a non-empty project\") }}\n{% endif %}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["bigquery","grants","missing-field"],"backgroundTag":"empty-required-field","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}