hasura/graphql-engine · error · Error
multiple definitions of graphql type: {0:}
Error message
multiple definitions of graphql type: {0:} What it means
Schema-building error: while merging type definitions from the parsed SDL, two definitions resolved to the same type name with conflicting definitions, so a single schema cannot be built. The conflicting ast::TypeName is reported.
Source
Thrown at v3/crates/graphql/lang-graphql/src/schema/build.rs:20
use thiserror::Error;
use crate::ast::common as ast;
use crate::ast::schema as sdl;
use crate::ast::schema::ConstDirective;
use crate::ast::spanning::Positioned;
use crate::ast::spanning::Spanning;
use crate::parser;
#[derive(Error, Debug, Clone)]
pub enum Error {
#[error("internal error when parsing introspection schema : {0:}")]
InternalParseError(Positioned<parser::Error>),
#[error("internal error when building schema: {0:}")]
Internal(String),
#[error("multiple definitions of graphql type: {0:}")]
ConflictingGraphQlType(ast::TypeName),
}
pub type Result<T> = core::result::Result<T, Error>;
pub fn build_schema<S>(s: &S) -> std::result::Result<Schema<S>, S::SchemaError>
where
S: SchemaContext,
{
let introspection_schema = include_str!("introspection.graphql");
let introspection_document = parser::Parser::new(introspection_schema)
.parse_schema_document()
.map_err(Error::InternalParseError)?;
let mut types = BTreeMap::new();
let mut introspection_root_fields = BTreeMap::new();
let mut builder = Builder {
registered_types: HashSet::new(),
registered_namespaces: HashSet::new(),View on GitHub (pinned to 724551b9ae)
Solutions
- Search the SDL for the reported type name and deduplicate/merge the definitions
- If merging files, exclude one of the conflicting definitions at load time
- If extending a type, use `extend type Foo` instead of redefining it
- Check generated SDL output for duplicated blocks after codegen changes
Example fix
# before
type User { id: ID }
type User { name: String }
# after
type User { id: ID, name: String }
# or: type User { id: ID } extend type User { name: String } Defensive patterns
Strategy: validation
Validate before calling
fn find_duplicate_types(docs: &[Document]) -> Vec<TypeName> {
let mut seen = HashSet::new();
docs.iter().flat_map(|d| d.definitions()).filter_map(|def| def.as_type_def())
.filter(|t| !seen.insert(t.name.clone())).map(|t| t.name.clone()).collect()
}
assert!(find_duplicate_types(&docs).is_empty()); Try / catch
match build_schema(&defs) { Err(Error::ConflictingGraphQlType(name)) => dedupe_or_report(name), _ => {} } — build_schema returns S::SchemaError, so map this variant at the call site. Prevention
- Deduplicate type definitions before merging schema files
- Use extend type instead of redefining
- Run schema linting in CI
When it happens
Trigger: Calling build_schema on a schema definition that defines the same type (e.g. type Foo {...} twice, or type Foo and interface/enum Foo) in separate definitions; also when stitching a base schema with introspection schema types that collide.
Common situations: Schema stitching or merging multiple .graphql files that both define a type; copy-pasted type blocks; re-importing a module that already declares a type; version bumps adding duplicate definitions to generated SDL.
Related errors
- no such field on type {type_name}: {field_name}
- multiple graphql types found with the same name: {graphql_ty
- the model {model_name} has a duplicate root field in the Gra
- unable to fetch introspection schema: %w
- error in fetching introspection schema: %w
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/5135eb70393f0ce6.
Report an issue: GitHub.