hasura/graphql-engine · error · DuplicateRootFieldError
Cannot add subscription root field {0} as it already in use
Error message
Cannot add subscription root field {0} as it already in use What it means
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.
Source
Thrown at v3/crates/metadata-resolve/src/helpers/types.rs:40
pub equal_operator: DataConnectorOperatorName,
}
/// Track the root fields of the GraphQL schema while resolving the metadata.
/// This is used to ensure that the schema has unique root fields for Query, Mutation and Subscription.
// NOTE: The `ast::Name` is cheap to clone, so storing them directly without references
pub struct TrackGraphQLRootFields {
pub query: BTreeSet<ast::Name>,
pub mutation: BTreeSet<ast::Name>,
pub subscription: BTreeSet<ast::Name>,
}
#[derive(Debug, thiserror::Error)]
pub enum DuplicateRootFieldError {
#[error("Cannot add query root field {0} as it already in use")]
Query(ast::Name),
#[error("Cannot add mutation root field {0} as it already in use")]
Mutation(ast::Name),
#[error("Cannot add subscription root field {0} as it already in use")]
Subscription(ast::Name),
}
impl TrackGraphQLRootFields {
pub fn new() -> Self {
Self {
query: BTreeSet::new(),
mutation: BTreeSet::new(),
subscription: BTreeSet::new(),
}
}
pub fn track_query_root_field(
&mut self,
name: &ast::Name,
) -> Result<(), DuplicateRootFieldError> {
if !self.query.insert(name.clone()) {
return Err(DuplicateRootFieldError::Query(name.clone()));
}View on GitHub (pinned to 724551b9ae)
Solutions
- Rename one of the colliding subscription root fields
- Disable the subscription on one of the models/commands if redundant
- Remove duplicated metadata entries
Example fix
# before Model A: subscription field "events" Model B: subscription field "events" # after Model B: subscription field "order_events"
Defensive patterns
Strategy: validation
Validate before calling
if !subscription_fields.insert(name.clone()) {
return Err(format!("duplicate subscription root field: {name}"));
} Try / catch
match err {
DuplicateRootFieldError::Subscription(name) => eprintln!("two subscriptions expose '{name}'; rename or disable one"),
_ => {}
} Prevention
- Give each model's subscription a distinct field name
- Audit subscription-enabled models when merging metadata
- Disable redundant subscriptions explicitly
When it happens
Trigger: 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.
Common situations: Enabling subscriptions on multiple models that resolve to the same field name, duplicated subscription metadata across environments.
Related errors
- Cannot add query root field {0} as it already in use
- Cannot add mutation root field {0} as it already in use
- the boolean expression type with name {type_name} is defined
- the following command is defined more than once: {name:}
- only one enumTypeNames can be defined in GraphqlConfig, whos
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/0cca254c121771d2.
Report an issue: GitHub.