hasura/graphql-engine · error · Error

a selection set is specified on field '{field_name}' of non-

Error message

a selection set is specified on field '{field_name}' of non-composite type: {type_name}

What it means

Thrown when a field whose GraphQL type is non-composite (scalar/enum) is selected with a sub-selection set, e.g. `name { first }` where `name: String`. Field selection sets are only legal on composite types (objects/interfaces/unions). The error carries the field name and the offending type name so you can locate the selection.

Source

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

    #[error("fragment cycle detected through: {0:?}")]
    CycleDetected(Vec<ast::Name>),
    // TODO, this error isn't thrown yet
    #[error("unused fragment: {0}")]
    FragmentNotUsed(ast::Name),
    #[error("fragment not defined in the document: {0}")]
    UnknownFragment(ast::Name),
    #[error("{} is defined on a non-composite type: {type_name}", match fragment_name { None => "inline fragment".to_owned(), Some(fragment_name) => format!("fragment {fragment_name}")})]
    FragmentOnNonCompositeType {
        fragment_name: Option<ast::Name>,
        type_name: ast::TypeName,
    },
    #[error("fragment of type {fragment_type} cannot be spread on type {selection_type}")]
    FragmentCannotBeSpread {
        selection_type: ast::TypeName,
        fragment_type: ast::TypeName,
    },
    // TODO, this error isn't thrown yet
    #[error(
        "a selection set is specified on field '{field_name}' of non-composite type: {type_name}"
    )]
    SelectionOnNonCompositeType {
        field_name: ast::Name,
        type_name: ast::TypeName,
    },
    #[error("no such field on type {type_name}: {field_name}")]
    NoFieldOnType {
        type_name: ast::TypeName,
        field_name: ast::Name,
    },
    #[error("no such type defined in the document: {0}")]
    UnknownType(ast::TypeName),
    #[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}'"
    )]

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Remove the sub-selection set from the non-composite field and select it as a leaf (`name` instead of `name { ... }`)
  2. If the field should have subfields, fix the schema so the field returns an object type
  3. Update/regenerate client queries after schema type changes

Example fix

// before
{ user { name { first } } }
// after
{ user { name } }
Defensive patterns

Strategy: validation

Validate before calling

let ft = schema.field_type(parent_type, field_name); if !ft.is_composite() { assert!(!selection.has_subselection(field_name), "scalar field cannot have a selection set"); }

Type guard

fn needs_selection_set(t: &Type) -> bool { t.is_composite() }

Try / catch

match validate(doc) { Err(Error::SelectionOnNonCompositeType { field_name, type_name }) => strip_subselection(field_name), r => r }

Prevention

When it happens

Trigger: Adding `{ ... }` braces after a scalar or enum field; treating a JSON-ish scalar as an object; querying a field whose type was changed from object to scalar/enum in the schema while keeping the old nested selection.

Common situations: Schema evolution flattened or scalarized a field but clients kept nested selections; custom scalars (e.g. JSON) mistakenly queried with subfields instead of being treated as opaque leaves; hand-writing queries without a schema-aware editor.

Related errors


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