SchemaTransformer.transformSchema produces schema with dangling reference to deleted type
Describe the bug
We've implemented a visitor that prunes our schema based on the presence of a directive.
This has worked well until quite recently, but has suddenly started failing with graphql.AssertException: Assert type Rom not found in schema.
I've analyzed the problem and reduced the schema and our visitor down to the minimal needed to reproduce the issue. Note that our actual implementation also handles other schema elements, but I don't think this is relevant for the issue at hand.
To Reproduce
Given the following schema, our visitor crashes with AssertException:
directive @remove on FIELD_DEFINITION type Query { rental: Rental @remove customer: Customer } type Store { inventory: Inventory @remove } type Inventory { store: Store @remove } type Customer { rental: Rental payment: Payment @remove } type Payment { inventory: Inventory @remove } type Rental { id: ID customer: Customer @remove }
Our visitor is defined as follows:
class SchemaPruningVisitor extends GraphQLTypeVisitorStub { @Override public TraversalControl visitGraphQLFieldDefinition(GraphQLFieldDefinition node, TraverserContext<GraphQLSchemaElement> context) { if (node.hasAppliedDirective("remove")) { return deleteNode(context); } return CONTINUE; } @Override public TraversalControl visitGraphQLObjectType(GraphQLObjectType node, TraverserContext<GraphQLSchemaElement> context) { if (node.getFields().stream().allMatch(field -> field.hasAppliedDirective("remove"))) { return deleteNode(context); } return CONTINUE; } }
Interesting observation
Note that if we flip the order of the Query.rental and Query.customer fields then our visitor no longer crashes and produces the schema we expect:
type Query { customer: Customer } type Customer { rental: Rental } type Rental { id: ID }