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
- Remove the sub-selection set from the non-composite field and select it as a leaf (`name` instead of `name { ... }`)
- If the field should have subfields, fix the schema so the field returns an object type
- 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
- Select scalars/enums as leaves with no braces
- Use a GraphQL LSP/editor that marks illegal sub-selections
- Treat custom JSON scalars as opaque leaves
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
- no fields are selected
- validation failed: {0}
- Unexpected value: expecting {expected_kind:}, but found: {fo
- '{name:}' is not a valid GraphQL name.
- '{alias:} is not a valid alias
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/add6c4edfc3491b4.
Report an issue: GitHub.