{"record":{"id":"0cca254c121771d2","repo":"hasura/graphql-engine","slug":"cannot-add-subscription-root-field-0-as-it-alrea","errorCode":null,"errorMessage":"Cannot add subscription root field {0} as it already in use","messagePattern":"Cannot add subscription root field (.+?) as it already in use","errorType":"validation","errorClass":"DuplicateRootFieldError","httpStatus":null,"severity":"error","filePath":"v3/crates/metadata-resolve/src/helpers/types.rs","lineNumber":40,"sourceCode":"    pub equal_operator: DataConnectorOperatorName,\n}\n\n/// Track the root fields of the GraphQL schema while resolving the metadata.\n/// This is used to ensure that the schema has unique root fields for Query, Mutation and Subscription.\n// NOTE: The `ast::Name` is cheap to clone, so storing them directly without references\npub struct TrackGraphQLRootFields {\n    pub query: BTreeSet<ast::Name>,\n    pub mutation: BTreeSet<ast::Name>,\n    pub subscription: BTreeSet<ast::Name>,\n}\n\n#[derive(Debug, thiserror::Error)]\npub enum DuplicateRootFieldError {\n    #[error(\"Cannot add query root field {0} as it already in use\")]\n    Query(ast::Name),\n    #[error(\"Cannot add mutation root field {0} as it already in use\")]\n    Mutation(ast::Name),\n    #[error(\"Cannot add subscription root field {0} as it already in use\")]\n    Subscription(ast::Name),\n}\n\nimpl TrackGraphQLRootFields {\n    pub fn new() -> Self {\n        Self {\n            query: BTreeSet::new(),\n            mutation: BTreeSet::new(),\n            subscription: BTreeSet::new(),\n        }\n    }\n    pub fn track_query_root_field(\n        &mut self,\n        name: &ast::Name,\n    ) -> Result<(), DuplicateRootFieldError> {\n        if !self.query.insert(name.clone()) {\n            return Err(DuplicateRootFieldError::Query(name.clone()));\n        }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/metadata-resolve/src/helpers/types.rs#L22-L58","documentation":"DuplicateRootFieldError::Subscription: two metadata components try to register a GraphQL subscription root field with the same name. Subscription root fields are tracked in their own BTreeSet, so collisions are detected independently of Query and Mutation.","triggerScenarios":"Defining two subscription-producing metadata objects (e.g. two models with subscriptions enabled, or commands exposed via subscription) whose GraphQL root field names are identical.","commonSituations":"Enabling subscriptions on multiple models that resolve to the same field name, duplicated subscription metadata across environments.","solutions":["Rename one of the colliding subscription root fields","Disable the subscription on one of the models/commands if redundant","Remove duplicated metadata entries"],"exampleFix":"# before\nModel A: subscription field \"events\"\nModel B: subscription field \"events\"\n\n# after\nModel B: subscription field \"order_events\"","handlingStrategy":"validation","validationCode":"if !subscription_fields.insert(name.clone()) {\n    return Err(format!(\"duplicate subscription root field: {name}\"));\n}","typeGuard":null,"tryCatchPattern":"match err {\n    DuplicateRootFieldError::Subscription(name) => eprintln!(\"two subscriptions expose '{name}'; rename or disable one\"),\n    _ => {}\n}","preventionTips":["Give each model's subscription a distinct field name","Audit subscription-enabled models when merging metadata","Disable redundant subscriptions explicitly"],"tags":["graphql","metadata","naming","duplicate","subscription"],"backgroundTag":"duplicate-graphql-field","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}