hasura/graphql-engine · error · DuplicateRootFieldError
Cannot add mutation root field {0} as it already in use
Error message
Cannot add mutation root field {0} as it already in use What it means
DuplicateRootFieldError::Mutation: the same situation as the Query variant but for the Mutation root type — two metadata entries attempt to register a GraphQL mutation root field with an identical name.
Source
Thrown at v3/crates/metadata-resolve/src/helpers/types.rs:38
pub struct NdcColumnForComparison {
pub column: DataConnectorColumnName,
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()) {View on GitHub (pinned to 724551b9ae)
Solutions
- Rename one mutation's GraphQL field name to be unique
- Remove the stale duplicate command from metadata
- Namespace mutation names per connector/domain (e.g. orders_insert vs users_insert)
Example fix
# before - kind: Command name: insert_user # in two different modules # after - kind: Command name: insert_user_v2 # unique name in the second module
Defensive patterns
Strategy: validation
Validate before calling
if !mutation_fields.insert(name.clone()) {
return Err(format!("duplicate mutation root field: {name}"));
} Try / catch
match err {
DuplicateRootFieldError::Mutation(name) => eprintln!("two mutations expose '{name}'; rename one"),
_ => {}
} Prevention
- Prefix mutations with entity + verb (user_insert, user_update)
- Namespace per connector when combining multiple data sources
- Check for clones after copy-pasting command metadata
When it happens
Trigger: Registering two mutations (commands) with the same GraphQL name on the Mutation root, e.g. two create_/update_ commands both named insert_user in different modules.
Common situations: Copy-pasted command definitions, multiple data connectors each defining a mutation with the same name, refactors that moved a command without renaming it.
Related errors
- Cannot add query root field {0} as it already in use
- Cannot add subscription 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/b9792bb33a8db661.
Report an issue: GitHub.