{"record":{"id":"3f1721178c4c68d7","repo":"hasura/graphql-engine","slug":"is-defined-on-a-non-composite-type-type-name","errorCode":null,"errorMessage":"{} is defined on a non-composite type: {type_name}","messagePattern":"(.+?) is defined on a non-composite type: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/graphql/lang-graphql/src/validation/error.rs","lineNumber":16,"sourceCode":"use thiserror::Error;\n\nuse 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}\")]","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/lang-graphql/src/validation/error.rs#L1-L34","documentation":"Thrown when a fragment (named or inline) declares an `on` target that is not a composite type (object, interface, or union) — e.g. `fragment F on Int` or an inline fragment on a scalar. Raised from collect.rs (collect_fields_internal / around line 299-323) during field collection; the error names either 'inline fragment' or 'fragment <name>' plus the offending type name. GraphQL only allows fragment type conditions on composite types.","triggerScenarios":"Writing `fragment F on String` (or any scalar/enum type) in a document; using an inline fragment `{ ... on MyEnum { ... } }` on a non-composite parent; applying fragments generated against a schema where the target used to be an object but is now a scalar/enum.","commonSituations":"Schema evolution changed a type from object to scalar or enum while stale queries still spread fragments on it; hand-written queries misunderstand that type conditions must be composite; codegen emitted fragments against the wrong schema version.","solutions":["Change the fragment's type condition to a composite type (object/interface/union) that exists in the schema","If the parent field is a scalar/enum, remove the fragment/selection set entirely and select the scalar leaf directly","Regenerate client queries against the current schema after schema changes"],"exampleFix":"// before\nfragment F on Int { ... }\n# after\nfragment F on User { id }","handlingStrategy":"validation","validationCode":"let t = schema.lookup(&fragment.type_condition); assert!(t.map(|t| t.is_composite()).unwrap_or(false), \"type condition must be composite\");","typeGuard":"fn is_composite(t: &Type) -> bool { matches!(t, Type::Object(_) | Type::Interface(_) | Type::Union(_)) }","tryCatchPattern":"match validate(doc) { Err(Error::FragmentOnNonCompositeType { fragment_name, type_name }) => fix_type_condition(fragment_name, type_name), r => r }","preventionTips":["Only write `on` conditions for object/interface/union types","Use schema-aware IDE tooling that flags invalid type conditions","Regenerate queries after schema type-kind changes"],"tags":["graphql","fragment","type-condition","validation"],"backgroundTag":"graphql-fragment-on-non-composite-type","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}