{"record":{"id":"99b7ee59d5456479","repo":"hasura/graphql-engine","slug":"fragment-of-type-fragment-type-cannot-be-spread","errorCode":null,"errorMessage":"fragment of type {fragment_type} cannot be spread on type {selection_type}","messagePattern":"fragment of type (.+?) cannot be spread on type (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/graphql/lang-graphql/src/validation/error.rs","lineNumber":21,"sourceCode":"use crate::ast::{common as ast, spanning};\n\npub type Result<T> = core::result::Result<T, Error>;\n\n#[derive(Error, Debug, Clone)]\npub enum Error {\n    #[error(\"fragment cycle detected through: {0:?}\")]\n    CycleDetected(Vec<ast::Name>),\n    // TODO, this error isn't thrown yet\n    #[error(\"unused fragment: {0}\")]\n    FragmentNotUsed(ast::Name),\n    #[error(\"fragment not defined in the document: {0}\")]\n    UnknownFragment(ast::Name),\n    #[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}\")})]\n    FragmentOnNonCompositeType {\n        fragment_name: Option<ast::Name>,\n        type_name: ast::TypeName,\n    },\n    #[error(\"fragment of type {fragment_type} cannot be spread on type {selection_type}\")]\n    FragmentCannotBeSpread {\n        selection_type: ast::TypeName,\n        fragment_type: ast::TypeName,\n    },\n    // TODO, this error isn't thrown yet\n    #[error(\n        \"a selection set is specified on field '{field_name}' of non-composite type: {type_name}\"\n    )]\n    SelectionOnNonCompositeType {\n        field_name: ast::Name,\n        type_name: ast::TypeName,\n    },\n    #[error(\"no such field on type {type_name}: {field_name}\")]\n    NoFieldOnType {\n        type_name: ast::TypeName,\n        field_name: ast::Name,\n    },\n    #[error(\"no such type defined in the document: {0}\")]","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/lang-graphql/src/validation/error.rs#L3-L39","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nfragment DogFrag on Dog { name }\nquery { cat { ...DogFrag } }\n// after\nfragment PetFrag on Pet { name }\nquery { cat { ...PetFrag } }","handlingStrategy":"validation","validationCode":"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\");","typeGuard":"fn types_overlap(schema: &Schema, a: &TypeName, b: &TypeName) -> bool { a == b || schema.share_interface_or_union(a, b) }","tryCatchPattern":"match validate(doc) { Err(Error::FragmentCannotBeSpread { selection_type, fragment_type }) => relocate_or_widen(fragment_type, selection_type), r => r }","preventionTips":["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"],"tags":["graphql","fragment-spread","type-mismatch","validation"],"backgroundTag":"graphql-fragment-cannot-spread","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}