GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

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) #4200

New issue
Copy link
New issue
Copy link
Closed
#4388
Closed
Empty union base definitions rejected before extensions are merged (spec violation)#4200
#4388
Copy link

Description

@rstata
rstata
opened on Jan 4, 2026
Issue body actions

Describe 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
        }
    }
}

Activity

  1. rstata commented on Jan 4, 2026

    @rstata
    rstata
    on Jan 4, 2026
    Author
    More actions

    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;
        }
      }
    }
    
  2. github-actions commented on Mar 5, 2026

    @github-actions
    github-actionsBot
    on Mar 5, 2026 – with GitHub Actions
    Contributor
    More actions

    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.

  3. github-actions
    added
    Stale
    on Mar 5, 2026
  4. dondonz
    added 2 commits that reference this issue on Mar 9, 2026

    Fix #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
  5. github-actions commented on Apr 4, 2026

    @github-actions
    github-actionsBot
    on Apr 4, 2026 – with GitHub Actions
    Contributor
    More actions

    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.

  6. github-actions
    closed this as not plannedon Apr 4, 2026
  7. andimarek
    reopened this on Apr 4, 2026
  8. github-actions
    removed
    Stale
    on Apr 5, 2026
  9. dondonz
    added a commit that references this issue on Apr 5, 2026

    Fix #4364 and #4200: nullable type bound and empty union extension su…

    7a3a541
  10. andimarek
    closed this as completedin #4388on May 20, 2026
  11. andimarek commented on May 20, 2026

    @andimarek
    andimarek
    on May 20, 2026
    Member
    More actions

    This is fixed in #4388

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.