hasura/graphql-engine · error · RelayError
'globalIdFields' for type {object_type:} found, but no model
Error message
'globalIdFields' for type {object_type:} found, but no model found with 'globalIdSource: true' for type {object_type:} What it means
Relay stage error: an object type declares globalIdFields, but no model implementing that object type is flagged globalIdSource: true. The Relay global ID machinery needs exactly one backing model to build IDs from those fields, so resolution fails when the flag is missing.
Source
Thrown at v3/crates/metadata-resolve/src/stages/relay/mod.rs:26
/// Ideally, we could move more Relay-based resolving into this discreet step, haven't
/// investigated this too deeply yet.
pub fn resolve(
global_id_enabled_types: BTreeMap<Qualified<CustomTypeName>, Vec<Qualified<ModelName>>>,
) -> Result<(), RelayError> {
// To check if global_id_fields are defined in object type but no model has global_id_source set to true:
// - Throw an error if no model with globalIdSource:true is found for the object type.
for (object_type, model_name_list) in global_id_enabled_types {
if model_name_list.is_empty() {
return Err(RelayError::GlobalIdSourceNotDefined { object_type });
}
}
Ok(())
}
#[derive(Debug, thiserror::Error)]
pub enum RelayError {
#[error(
"'globalIdFields' for type {object_type:} found, but no model found with 'globalIdSource: true' for type {object_type:}"
)]
GlobalIdSourceNotDefined {
object_type: Qualified<CustomTypeName>,
},
#[error(
"Model {model_name:} is marked as a global ID source but there are no global id fields present in the related object type {type_name:}"
)]
NoGlobalFieldsPresentInGlobalIdSource {
type_name: Qualified<CustomTypeName>,
model_name: ModelName,
},
#[error(
"Found multiple models {model_1:}, {model_2:} that implement the same object type {object_type:} to be global ID sources."
)]
DuplicateModelGlobalIdSource {
model_1: Qualified<ModelName>,
model_2: Qualified<ModelName>,View on GitHub (pinned to 724551b9ae)
Solutions
- Find the model that implements the object type named in the error and set globalIdSource: true on it
- Verify the model's object type mapping actually points at the annotated type
- If globalIdFields were added by mistake, remove them from the object type
Example fix
# before kind: Model name: Users objectType: User # type User has globalIdFields: [id] # after kind: Model name: Users objectType: User globalIdSource: true
Defensive patterns
Strategy: validation
Validate before calling
fn check_global_id_pairs(models: &[Model], types: &[ObjectType]) -> Result<(), String> {
for t in types {
if t.global_id_fields.is_empty() { continue; }
let ok = models.iter().any(|m| m.object_type == t.name && m.global_id_source);
if !ok { return Err(format!("type {} has globalIdFields but no globalIdSource model", t.name)); }
}
Ok(())
} Try / catch
match on RelayError::GlobalIdSourceNotDefined and print the object type plus the models implementing it to guide the fix
Prevention
- Add globalIdSource flag and globalIdFields in the same commit
- Codemod or lint rule pairing the two settings per object type
When it happens
Trigger: Adding globalIdFields to an object type in OpenDD metadata without setting globalIdSource: true on any model that implements that type; or setting the flag on a model targeting a different object type.
Common situations: Enabling Relay-style pagination incrementally — the type annotation lands but the model flag is forgotten; refactoring model-to-type mappings so the flagged model no longer implements the annotated type.
Related errors
- Model {model_name:} is marked as a global ID source but ther
- Found multiple models {model_1:}, {model_2:} that implement
- model {model_name:} with arguments is unsupported as a globa
- Relationship {relationship_name} could not be found for type
- Multiple relationships named {relationship_name} defined for
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/56c0516898ae006e.
Report an issue: GitHub.