Skip to content

feat: validate input types during schema compilation - #713

Merged
stuebingerb merged 1 commit into
mainfrom
feature/improve-input-type-validation
Aug 16, 2026
Merged

feat: validate input types during schema compilation#713
stuebingerb merged 1 commit into
mainfrom
feature/improve-input-type-validation

Conversation

@stuebingerb

Copy link
Copy Markdown
Owner

Ensures that abstract and sealed classes as input types are already caught at schema compilation instead of failing at runtime, and improves the error message for interfaces as input types.

Resolves #712

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3bccc5ef-147c-42e3-b347-9604e76d4358

📥 Commits

Reviewing files that changed from the base of the PR and between 508d558 and 5c423ff.

📒 Files selected for processing (2)
  • kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt
  • kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/specification/typesystem/InputObjectsSpecificationTest.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Sealed classes remain supported as query types and continue to generate unions.
    • Sealed classes, interfaces, and abstract classes are now rejected as input types.
    • Improved error messages for unsupported input declarations, including nested and inferred types.
  • Tests

    • Added coverage for invalid input registrations, resolver inference, sealed interfaces, sealed classes, and abstract classes.
    • Updated empty-input validation to confirm explicit registration behavior.

Walkthrough

Schema compilation now rejects interfaces, sealed classes, and abstract classes as input types with specific SchemaException messages. Sealed query types still generate unions. Tests cover inferred, registered, nested, nullable, and list-based input types.

Changes

Input Type Validation

Layer / File(s) Summary
Sealed type routing
kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt
Sealed types generate unions only for query types. Input types proceed to input validation.
Input type rejection and coverage
kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt, kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/specification/typesystem/InputObjectsSpecificationTest.kt
Input compilation rejects interfaces, sealed classes, and abstract classes before constructor resolution. Tests cover inferred and explicitly registered input types, including nested, nullable, and list-based fields.

Merge Risk: ⚪ Minimal · up to 5c423

This change moves invalid input-type failures to schema compilation and improves the related error message; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the conventional commit format and clearly describes input-type validation, but it is slightly above the 50-character guideline.
Description check ✅ Passed The description directly explains schema-compilation validation for abstract and sealed input types and improved interface errors.
Linked Issues check ✅ Passed The changes validate invalid input types during compilation and reject interfaces, sealed classes, sealed interfaces, and abstract classes as required by issue #712.
Out of Scope Changes check ✅ Passed The implementation and tests focus on invalid input-type validation and related error behavior, with no unrelated changes identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/improve-input-type-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cf633ac2-cd7e-4d25-b166-37efa3096f34

📥 Commits

Reviewing files that changed from the base of the PR and between adaa3ef and 2adb1a5.

📒 Files selected for processing (2)
  • kgraphql/src/main/kotlin/de/stuebingerb/kgraphql/schema/structure/SchemaCompilation.kt
  • kgraphql/src/test/kotlin/de/stuebingerb/kgraphql/specification/typesystem/InputObjectsSpecificationTest.kt

@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.10%. Comparing base (64d998a) to head (5c423ff).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #713      +/-   ##
==========================================
+ Coverage   84.05%   84.10%   +0.05%     
==========================================
  Files         151      151              
  Lines        4930     4933       +3     
  Branches      853      855       +2     
==========================================
+ Hits         4144     4149       +5     
+ Misses        488      487       -1     
+ Partials      298      297       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Architecture diagram
sequenceDiagram
    participant App as Application
    participant Comp as SchemaCompilation
    participant Resolver as Resolver Builder
    participant Input as handleInputType()
    participant Output as handleOutputType()

    Note over App,Output: PR: Input type validation during schema compilation

    App->>Comp: Build schema (query + input types)
    Comp->>Resolver: Resolve query resolver
    Resolver->>Comp: Returns type reference
    Comp->>Comp: Determine TypeCategory (QUERY/INPUT)
    alt TypeCategory == QUERY (output position)
        Comp->>Output: Handle output type
        alt Class is sealed
            Output-->>Comp: TypeDef.Union
            Note over Output: Sealed classes allowed as output types
        else Class is not sealed
            Output-->>Comp: Regular output type
        end
    else TypeCategory == INPUT
        alt Class is sealed
            Comp->>Input: Validate input class
            Input-->>Comp: SchemaException ("Sealed class ... not allowed as input type")
            Comp-->>App: Throw at compile time
        else Class is interface
            Input-->>Comp: SchemaException ("Interface ... not allowed as input type")
            Comp-->>App: Throw at compile time
        else Class is abstract
            Input-->>Comp: SchemaException ("Abstract class ... not allowed as input type")
            Comp-->>App: Throw at compile time
        else Class is valid input type
            Input->>Input: Validate primary constructor
            Input-->>Comp: TypeDef.InputObject
            Comp-->>App: Schema compiled successfully
        end
    end
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown

🐰 Bencher Report

ProjectKGraphQL
Branchfeature/improve-input-type-validation
Testbedubuntu-latest
Click to view all benchmark results
BenchmarkThroughputBenchmark Result
operations / second (ops/s)
(Result Δ%)
Lower Boundary
operations / second (ops/s)
(Limit %)
de.stuebingerb.kgraphql.FunctionExecutionBenchmark.benchmarkFunctionExecution📈 view plot
🚷 view threshold
5,446,846.14 ops/s
(-5.04%)Baseline: 5,736,207.35 ops/s
4,965,205.69 ops/s
(91.16%)
de.stuebingerb.kgraphql.ParallelExecutionBenchmark.queryBenchmark📈 view plot
🚷 view threshold
1.30 ops/s
(+0.04%)Baseline: 1.30 ops/s
1.30 ops/s
(99.80%)
de.stuebingerb.kgraphql.QueryBenchmark.executionError📈 view plot
🚷 view threshold
21,396.69 ops/s
(+20.92%)Baseline: 17,695.26 ops/s
11,112.66 ops/s
(51.94%)
de.stuebingerb.kgraphql.QueryBenchmark.inputFromDocument📈 view plot
🚷 view threshold
24,762.88 ops/s
(+14.49%)Baseline: 21,628.88 ops/s
14,473.53 ops/s
(58.45%)
de.stuebingerb.kgraphql.QueryBenchmark.inputFromVariable📈 view plot
🚷 view threshold
24,241.78 ops/s
(+15.56%)Baseline: 20,976.96 ops/s
14,218.27 ops/s
(58.65%)
de.stuebingerb.kgraphql.QueryBenchmark.largeList📈 view plot
🚷 view threshold
4.58 ops/s
(-2.87%)Baseline: 4.72 ops/s
4.15 ops/s
(90.51%)
de.stuebingerb.kgraphql.QueryBenchmark.largeListWithFragment📈 view plot
🚷 view threshold
5.02 ops/s
(-4.26%)Baseline: 5.25 ops/s
4.63 ops/s
(92.13%)
de.stuebingerb.kgraphql.QueryBenchmark.manyChildren📈 view plot
🚷 view threshold
174.90 ops/s
(-4.85%)Baseline: 183.82 ops/s
145.30 ops/s
(83.08%)
de.stuebingerb.kgraphql.QueryBenchmark.manyChildrenWithFragment📈 view plot
🚷 view threshold
193.86 ops/s
(-0.91%)Baseline: 195.64 ops/s
156.82 ops/s
(80.89%)
de.stuebingerb.kgraphql.QueryBenchmark.manyDataChildren📈 view plot
🚷 view threshold
8.91 ops/s
(-0.02%)Baseline: 8.91 ops/s
8.80 ops/s
(98.79%)
de.stuebingerb.kgraphql.QueryBenchmark.manyOperations📈 view plot
🚷 view threshold
308.08 ops/s
(+0.63%)Baseline: 306.16 ops/s
247.41 ops/s
(80.31%)
de.stuebingerb.kgraphql.QueryBenchmark.manyOperationsWithFragment📈 view plot
🚷 view threshold
304.44 ops/s
(-3.64%)Baseline: 315.93 ops/s
261.47 ops/s
(85.89%)
de.stuebingerb.kgraphql.QueryBenchmark.nestedObject📈 view plot
🚷 view threshold
9,165.50 ops/s
(+16.40%)Baseline: 7,874.34 ops/s
6,143.69 ops/s
(67.03%)
de.stuebingerb.kgraphql.RequestCachingBenchmark.invalidRequest📈 view plot
🚷 view threshold
142,194.02 ops/s
(+0.23%)Baseline: 141,862.80 ops/s
132,981.54 ops/s
(93.52%)
de.stuebingerb.kgraphql.RequestCachingBenchmark.largeRequest📈 view plot
🚷 view threshold
9,393.28 ops/s
(+16.00%)Baseline: 8,098.00 ops/s
5,993.11 ops/s
(63.80%)
de.stuebingerb.kgraphql.RequestCachingBenchmark.smallRequest📈 view plot
🚷 view threshold
13,389.75 ops/s
(+15.12%)Baseline: 11,631.38 ops/s
8,460.32 ops/s
(63.19%)
de.stuebingerb.kgraphql.SimpleExecutionOverheadBenchmark.benchmark📈 view plot
🚷 view threshold
487,547.44 ops/s
(+3.21%)Baseline: 472,361.34 ops/s
442,518.88 ops/s
(90.76%)
🐰 View full continuous benchmarking report in Bencher

@stuebingerb
stuebingerb force-pushed the feature/improve-input-type-validation branch from 2adb1a5 to 508d558 Compare August 14, 2026 15:50

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Architecture diagram
sequenceDiagram
    participant SchemaBuilder as Schema Builder
    participant Compiler as SchemaCompilation
    participant TypeHandler as Type Handler
    participant QueryType as Query Type Resolver
    participant InputType as Input Type Handler
    participant Validator as Validator

    Note over SchemaBuilder,Validator: Schema compilation and type validation flow

    SchemaBuilder->>Compiler: Build schema
    Compiler->>QueryType: Handle query type
    QueryType->>TypeHandler: Resolve query type
    TypeHandler->>TypeHandler: Check sealed class
    
    alt Sealed class and QUERY category
        TypeHandler->>TypeHandler: Create Union type
    else Sealed class and INPUT category
        TypeHandler->>InputType: Handle as input type
    end

    Compiler->>InputType: Handle input type
    InputType->>Validator: Validate input type
    
    alt Input type is interface
        Validator-->>InputType: Validation error
        InputType-->>Compiler: SchemaException - Interface not allowed
        Compiler-->>SchemaBuilder: Propagate schema error
    else Input type is sealed class
        Validator-->>InputType: Validation error
        InputType-->>Compiler: SchemaException - Sealed class not allowed
        Compiler-->>SchemaBuilder: Propagate schema error
    else Input type is abstract class
        Validator-->>InputType: Validation error
        InputType-->>Compiler: SchemaException - Abstract class not allowed
        Compiler-->>SchemaBuilder: Propagate schema error
    else Input type is valid
        Validator-->>InputType: Valid input type
        InputType->>InputType: Get primary constructor
        alt No primary constructor
            InputType-->>Compiler: SchemaException - Java class unsupported
            Compiler-->>SchemaBuilder: Propagate schema error
        else Constructor exists
            InputType-->>Compiler: Continue processing
            Compiler-->>SchemaBuilder: Schema compiled successfully
        end
    end
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Ensures that abstract and sealed classes as input types are already
caught at schema compilation instead of failing at runtime, and
improves the error message for interfaces as input types.

Resolves #712
@stuebingerb
stuebingerb force-pushed the feature/improve-input-type-validation branch from 508d558 to 5c423ff Compare August 15, 2026 13:16
Comment on lines -291 to -295
when (val type = unions.find { it.name == kClass.simpleName }) {
null -> Unit
else -> return type
}

@stuebingerb stuebingerb Aug 15, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines were added with aPureBase/KGraphQL#110 but the corresponding test (moved to UnionsSpecificationTest#list of union type should work as expected) still runs successfully. In fact, the only test that even reached line 293 was the new use case added in input objects must not be sealed classes - and that clearly shouldn't have, so... unsure what impact this has, I wasn't able to come up with a test that would break.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant Client as "Client/Test"
    participant Schema as "KGraphQL.schema builder"
    participant Compiler as "SchemaCompilation"
    participant InputHandler as "handleInputType()"
    participant TypeRegistry as "Type Proxies/Registry"
    participant Validator as "assertValidObjectType()"
    
    Note over Client,Validator: Schema Compilation - Input Type Validation Flow
    
    Client->>Schema: Build schema with query/type/inputType definitions
    Schema->>Compiler: Compile schema
    Compiler->>Compiler: handlePossiblyWrappedType()
    
    alt TypeCategory == QUERY
        Compiler->>Compiler: Handle as output type
    else TypeCategory == INPUT
        Compiler->>InputHandler: delegate to handleInputType(kClass)
        InputHandler->>Validator: assertValidObjectType(kClass)
        
        alt kClass is Interface
            InputHandler->>InputHandler: CHANGED: Detect interface type
            InputHandler->>Schema: Throw SchemaException
            Note over InputHandler,Schema: Interface 'X' is not allowed as input type
        else kClass is Sealed class
            InputHandler->>InputHandler: CHANGED: Detect sealed class type
            InputHandler->>Schema: Throw SchemaException
            Note over InputHandler,Schema: Sealed class 'X' is not allowed as input type
        else kClass is Abstract class
            InputHandler->>InputHandler: CHANGED: Detect abstract class type
            InputHandler->>Schema: Throw SchemaException
            Note over InputHandler,Schema: Abstract class 'X' is not allowed as input type
        else Valid concrete class
            InputHandler->>InputHandler: Process primary constructor
            InputHandler->>TypeRegistry: Check for existing cached types
            alt Cached type found
                TypeRegistry-->>InputHandler: Return cached type
            else No cache
                InputHandler->>TypeRegistry: Register new input type
                TypeRegistry-->>Schema: Return compiled type
            end
        end
    end
    
    Note over Schema,Validator: Nested type validation (recursive)
    
    Compiler->>Compiler: Handle nested generic types
    Compiler->>InputHandler: Recursively validate nested input fields
    InputHandler->>Validator: Validate nested type class
    alt Nested type is abstract/sealed/interface
        Validator-->>InputHandler: Invalid type detected
        InputHandler->>Schema: Throw SchemaException
    else Valid nested type
        Validator-->>InputHandler: Validation passed
        InputHandler-->>Compiler: Continue compilation
    end
    
    Note over Client,Schema: Cached Type Lookup (CHANGED behavior)
    
    Compiler->>TypeRegistry: Check cached instances
    alt Query type category
        TypeRegistry-->>Compiler: Check queryTypeProxies
    else Input type category
        TypeRegistry-->>Compiler: Check inputTypeProxies
    end
    
    opt No cached type found
        Compiler->>InputHandler: Create new type definition
        InputHandler-->>Compiler: Return type
    end
    
    Compiler-->>Schema: Compiled schema with validated types
    Schema-->>Client: Return schema or throw SchemaException
Loading

Re-trigger cubic

@stuebingerb
stuebingerb merged commit 9ab0d74 into main Aug 16, 2026
14 checks passed
@stuebingerb
stuebingerb deleted the feature/improve-input-type-validation branch August 16, 2026 09:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schema validation should catch invalid input types

1 participant