{"record":{"id":"6aa9928feb232e9c","repo":"hasura/graphql-engine","slug":"multiple-models-are-marked-as-entity-source-for-th","errorCode":null,"errorMessage":"multiple models are marked as entity source for the object type {type_name:}","messagePattern":"multiple models are marked as entity source for the object type (.+?)","errorType":"validation","errorClass":"ApolloError","httpStatus":null,"severity":"error","filePath":"v3/crates/metadata-resolve/src/stages/apollo/mod.rs","lineNumber":69,"sourceCode":"    #[error(\n        \"'apolloFederation.keys' for type {object_type:} found, but no model found with 'apolloFederation.entitySource: true' for type {object_type:}\"\n    )]\n    ApolloFederationEntitySourceNotDefined {\n        object_type: Qualified<CustomTypeName>,\n    },\n    #[error(\n        \"model {model_name:} with arguments is unsupported as an Apollo Federation entity source\"\n    )]\n    ModelWithArgumentsAsApolloFederationEntitySource { model_name: Qualified<ModelName> },\n\n    #[error(\n        \"Model {model_name:} is marked as an Apollo Federation entity source but there are no keys fields present in the related object type {type_name:}\"\n    )]\n    NoKeysFieldsPresentInEntitySource {\n        type_name: Qualified<CustomTypeName>,\n        model_name: ModelName,\n    },\n    #[error(\"multiple models are marked as entity source for the object type {type_name:}\")]\n    MultipleEntitySourcesForType {\n        type_name: Qualified<CustomTypeName>,\n    },\n}\n","sourceCodeStart":51,"sourceCodeEnd":74,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/metadata-resolve/src/stages/apollo/mod.rs#L51-L74","documentation":"The Apollo Federation stage enforces that each object type has at most one entity source. This error fires when two or more models mapped to the same object type are all marked apolloFederation.entitySource: true, making it ambiguous which model serves entity resolutions for that type.","triggerScenarios":"Marking two models that map to the same graphql type_name with apolloFederation.entitySource: true — e.g. a table-backed model and a command-backed model both exposing the same type.","commonSituations":"Adding a new model for the same type (e.g. a command variant) and copying the federation flags over; refactoring one type into multiple models and leaving entitySource on both; copy-paste of model configuration blocks.","solutions":["Choose exactly one model to be the entity source for the type and set apolloFederation.entitySource: true only on it.","Remove the entitySource flag (or the whole apolloFederation block) from the other models mapping to the same type_name.","If both models genuinely need to serve entity data, consolidate them or expose one as a relationship/command instead."],"exampleFix":"# before\nmodels:\n  users_table:\n    graphql: { type_name: users }\n    apolloFederation: { entitySource: true }\n  users_api:\n    graphql: { type_name: users }\n    apolloFederation: { entitySource: true }\n# after\nmodels:\n  users_table:\n    graphql: { type_name: users }\n    apolloFederation: { entitySource: true }\n  users_api:\n    graphql: { type_name: users }\n    # entitySource removed","handlingStrategy":"validation","validationCode":"use std::collections::HashMap;\nfn single_entity_source(models: &[Model]) -> bool {\n    let mut counts: HashMap<&str, usize> = HashMap::new();\n    for m in models {\n        if m.apollo_federation.as_ref().map(|a| a.entity_source).unwrap_or(false) {\n            *counts.entry(m.graphql.type_name.as_str()).or_default() += 1;\n        }\n    }\n    counts.values().all(|c| *c <= 1)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one authoritative model per federation entity type.","When splitting a type across models, decide the single entity source up front."],"tags":["hasura","apollo-federation","metadata","entity-source","conflict"],"backgroundTag":"apollo-federation-misconfiguration","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}