hasura/graphql-engine · error · Error
fragment of type {fragment_type} cannot be spread on type {s
Error message
fragment of type {fragment_type} cannot be spread on type {selection_type} What it means
Thrown when a named fragment's type condition cannot overlap the type of the selection set where it is spread — e.g. spreading `fragment DogFragment on Dog` inside a selection on type `Cat` with no common union/interface. Produced in collect.rs:152 (collect_fields_from_fragment) when the fragment's type does not intersect the current selection type. This is the spec's 'Fragments must be specified on types that exist in the schema' / spread applicability rule.
Source
Thrown at v3/crates/graphql/lang-graphql/src/validation/error.rs:21
use crate::ast::{common as ast, spanning};
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Error, Debug, Clone)]
pub enum Error {
#[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}")]View on GitHub (pinned to 724551b9ae)
Solutions
- Move the fragment spread to a field whose type matches (or shares an interface/union with) the fragment's type condition
- Widen the fragment's type condition to a common interface or union that covers both types
- After schema changes, re-run codegen/lint so fragment spreads are re-checked
Example fix
// before
fragment DogFrag on Dog { name }
query { cat { ...DogFrag } }
// after
fragment PetFrag on Pet { name }
query { cat { ...PetFrag } } Defensive patterns
Strategy: validation
Validate before calling
let frag_t = schema.concrete_type_for_fragment(&f.name); let sel_t = schema.type_of_field(&parent_field); assert!(types_overlap(&schema, &frag_t, &sel_t), "fragment {f.name} cannot apply here"); Type guard
fn types_overlap(schema: &Schema, a: &TypeName, b: &TypeName) -> bool { a == b || schema.share_interface_or_union(a, b) } Try / catch
match validate(doc) { Err(Error::FragmentCannotBeSpread { selection_type, fragment_type }) => relocate_or_widen(fragment_type, selection_type), r => r } Prevention
- Spread fragments only under fields whose type matches or shares an interface/union with the type condition
- Prefer interfaces as type conditions for reusable fragments
- Re-lint fragments after schema return-type changes
When it happens
Trigger: Spreading `...DogFrag` inside a field whose type is a different object type with no shared interface/union; moving a fragment spread into a field whose return type changed in the schema; copying a fragment from one part of the query to an incompatible branch.
Common situations: Schema change altered a field's return type so existing fragment spreads no longer apply; large queries reuse fragments across branches assuming a shared interface that was removed; copy-paste of spreads between operations during refactoring.
Related errors
- Unexpected value: expecting {expected_kind:}, but found: {fo
- validation failed: {0}
- '{name:}' is not a valid GraphQL name.
- '{alias:} is not a valid alias
- {value} is not a valid limit value
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/99b7ee59d5456479.
Report an issue: GitHub.