GeezerVison is showing github.com — Empty union base definitions rejected before extensions are merged (spec violation) · Issue #4200 · graphql-java/graphql-java
Empty union base definitions rejected before extensions are merged (spec violation) #4200DescriptionDescribe the bug
The spec grammar:
(UnionTypeDefinition : Description? union Name Directives[Const]? UnionMemberTypes?)
makes UnionMemberTypes optional. SchemaParser correctly parses this SDL and TypeDefinitionRegistry correctly shows the union extensions. However, SchemaGenerator.makeExecutableSchema() fails validation with:
SchemaProblem{errors=[Union type 'Pet' must include one or more member types.]}
Root cause is that the validation checks the base definition before merging extension members (which isn't done for other types like interfaces). For deeper dive on root cause see this link.
(GraphQL Java 25.0)
To Reproduce
import graphql.schema.idl.SchemaParser
import graphql.schema.idl.UnExecutableSchemaGenerator
import org.junit.jupiter.api.Test
/**
* Demonstrates a graphql-java bug: empty union base definitions with members
* added via extensions are rejected, even though the GraphQL spec allows this.
*
* The spec grammar (UnionTypeDefinition : Description? union Name Directives[Const]? UnionMemberTypes?)
* makes UnionMemberTypes optional. SchemaParser correctly parses this SDL and
* TypeDefinitionRegistry correctly shows the union extensions. However,
* SchemaGenerator.makeExecutableSchema() fails validation with:
*
* SchemaProblem{errors=[Union type 'Pet' must include one or more member types.]}
*
* The validation checks the base definition before merging extension members.
*/
class UnionTest {
@Test
fun `test empty union base`() {
val sdl = """
type Cat { meow: String }
type Dog { bark: String }
union Pet
extend union Pet = Cat | Dog
type Query { pet: Pet }
""".trimIndent()
val registry = SchemaParser().parse(sdl)
println("=== Registry parsed successfully ===")
println("Types: ${registry.types().keys}")
println("Union extensions: ${registry.unionTypeExtensions()}")
try {
val schema = UnExecutableSchemaGenerator.makeUnExecutableSchema(registry)
println("=== Schema built successfully ===")
} catch (e: Exception) {
println("=== Exception ===")
println("Class: ${e.javaClass.name}")
println("Message: ${e.message}")
e.printStackTrace()
throw e
}
}
}
Activityrstata commented on Jan 4, 2026 Java rewrite:
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import graphql.schema.idl.UnExecutableSchemaGenerator;
import org.junit.jupiter.api.Test;
class UnionTest {
/**
* Demonstrates a graphql-java bug: empty union base definitions with members
* added via extensions are rejected, even though the GraphQL spec allows this.
*
* Expected failure (current graphql-java behavior):
*
* SchemaProblem{errors=[Union type 'Pet' must include one or more member types.]}
*/
@Test
void testEmptyUnionBase() {
String sdl = String.join("\n",
"type Cat { meow: String }",
"type Dog { bark: String }",
"union Pet",
"extend union Pet = Cat | Dog",
"type Query { pet: Pet }"
);
TypeDefinitionRegistry registry = new SchemaParser().parse(sdl);
System.out.println("=== Registry parsed successfully ===");
System.out.println("Types: " + registry.types().keySet());
System.out.println("Union extensions: " + registry.unionTypeExtensions());
try {
UnExecutableSchemaGenerator.makeUnExecutableSchema(registry);
System.out.println("=== Schema built successfully ===");
} catch (Exception e) {
System.out.println("=== Exception ===");
System.out.println("Class: " + e.getClass().getName());
System.out.println("Message: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
}
github-actions commented on Mar 5, 2026 Hello, this issue has been inactive for 60 days, so we're marking it as stale. If you would like to continue this discussion, please comment within the next 30 days or we'll close the issue. added 2 commits that reference this issue on Mar 9, 2026Fix #4200: Allow empty union base definitions when extensions add mem… This issue will close once commit f740eb7 is merged into the 'master' branch.f740eb7 Fix #4200: Allow empty union definitions when extensions provide members This issue will close once commit 6989cde is merged into the 'master' branch.6989cde github-actions commented on Apr 4, 2026 Hello, as this issue has been inactive for 90 days, we're closing the issue. If you would like to resume the discussion, please create a new issue. andimarek commented on May 20, 2026
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|