hasura/graphql-engine · error · Error

fields of different type {type1} and {type2} cannot be merge

Error message

fields of different type {type1} and {type2} cannot be merged under the same alias: {alias}

What it means

Thrown by the FieldsCanMerge rule when two fields with the same response key (alias) have different return types in the schema, e.g. one selection of `a: name` (String) and another `a: age` types clashing, or the same field name returning incompatible types on different branches (fragments on different types). Merging would require serializing two incompatible types into one response key, so validation fails with both types and the alias.

Source

Thrown at v3/crates/graphql/lang-graphql/src/validation/error.rs:59

    #[error("an internal error occurred during validation: type lookup failed for {type_name}")]
    InternalTypeNotFound { type_name: ast::TypeName },
    #[error(
        "an internal error occurred during validation: field {field_name} lookup failed for sub type '{sub_type_name}' of type '{type_name}'"
    )]
    InternalNoFieldOnSubtype {
        type_name: ast::TypeName,
        sub_type_name: ast::TypeName,
        field_name: ast::Name,
    },
    #[error(
        "different fields {field1} and {field2} cannot be merged under the same alias: {alias}"
    )]
    FieldsConflictDifferentFields {
        alias: ast::Alias,
        field1: ast::Name,
        field2: ast::Name,
    },
    #[error(
        "fields of different type {type1} and {type2} cannot be merged under the same alias: {alias}"
    )]
    FieldsConflictDifferingTypes {
        alias: ast::Alias,
        type1: ast::Type,
        type2: ast::Type,
    },
    #[error("cannot merge fields with different arguments on the same alias: {alias}")]
    FieldsConflictDifferingArguments {
        alias: ast::Alias,
        location1: Option<spanning::SourcePosition>,
        location2: Option<spanning::SourcePosition>,
    },
    #[error("the string {str} in the provided json value is not a valid GraphQL name")]
    NotAValidName { str: String },
    #[error("expected a value of type {expected_type} but found a value of type {actual_type}")]
    IncorrectFormat {
        expected_type: &'static str,

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Rename one alias so the two fields occupy different response keys
  2. If both selections should merge, make the field types identical (fix schema or select the same field)
  3. For same-named fields on different concrete types, select them in mutually exclusive fragments (`... on A`, `... on B`) so they never overlap

Example fix

// before
{ x: user { name } x: item { title } }
// after
{ u: user { name } i: item { title } }
Defensive patterns

Strategy: validation

Validate before calling

for (key, fields) in group_by_response_key(selection) { let mut types = fields.iter().map(|f| schema.field_type(&f.name)); assert!(all_same_type(&mut types), "conflicting types under alias {key}"); }

Type guard

fn mergeable(t1: &Type, t2: &Type) -> bool { t1 == t2 }

Try / catch

match validate(doc) { Err(Error::FieldsConflictDifferingTypes { alias, .. }) => rename_alias(alias), r => r }

Prevention

When it happens

Trigger: Aliasing fields of different GraphQL types to the same key within overlapping selections; spreading fragments on different object types (no shared interface) that each define a field with the same name but different types under the same alias; schema change altering a field's type so previously-mergeable selections now conflict.

Common situations: Union/parallel fragment spreads where same-named fields on different types diverge in type; schema evolution changing a field from `String` to `[String]` breaking merged selections; large generated queries combining fragment selections on intersecting types.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/e65b2ef07d00f1e7. Report an issue: GitHub.