You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When an ExecutableDocument contains a fragment that is not referenced by any operation, directive argument validation is skipped entirely for that fragment. Only the "unused fragment" diagnostic is reported — unknown arguments, missing required arguments, etc. are silently ignored.
This is a problem for LSP-like tooling where individual fragments are validated in isolation (without a corresponding operation in the same document).
Reproduction
let schema = Schema::parse_and_validate("directive @d(a: Int) on FRAGMENT_DEFINITION\ntype Query { f: Int }","s.graphql",).unwrap();// Referenced by an operation — unknown arg `bad` IS reported ✅let err = ExecutableDocument::parse_and_validate(&schema,"query { ...F }\nfragment F on Query @d(bad: 1) { f }","ref.graphql",).unwrap_err().errors.to_string();assert!(err.contains("is not supported by `@d`"));// NOT referenced by an operation — unknown arg `bad` is NOT reported ❌let err = ExecutableDocument::parse_and_validate(&schema,"fragment F on Query @d(bad: 1) { f }","standalone.graphql",).unwrap_err().errors.to_string();// Only error is: fragment `F` must be used in an operation// No directive argument validation occursassert!(err.contains("is not supported by `@d`"));// FAILS
validate_operation_definitions — iterates operations only
validate_fragments_used — only checks whether fragments are referenced, never validates their contents
Fragment definitions are only validated via validate_fragment_definition, which is only reachable through validate_fragment_spread — i.e., a fragment spread in an operation's selection set. Orphan fragments never enter this path.
Expected behavior
Directive arguments (and other fragment-level validation) should be reported regardless of whether the fragment is used in an operation.
Possible approaches
Always validate all fragment definitions: In validate_with_or_without_schema (or validate_executable_document), iterate document.fragments directly and call validate_fragment_definition for each, independent of reachability from operations. This is the simplest fix but changes the existing behavior for all callers.
Configurable validation via an option: Add an option to ExecutableDocument::validate (or a new method) that controls whether unused fragments receive full validation. This would let LSP tooling opt in without affecting the default behavior for spec-strict use cases.
Description
When an
ExecutableDocumentcontains a fragment that is not referenced by any operation, directive argument validation is skipped entirely for that fragment. Only the "unused fragment" diagnostic is reported — unknown arguments, missing required arguments, etc. are silently ignored.This is a problem for LSP-like tooling where individual fragments are validated in isolation (without a corresponding operation in the same document).
Reproduction
Cause
validate_with_or_without_schema(executable/validation.rs:40-48) calls:validate_operation_definitions— iterates operations onlyvalidate_fragments_used— only checks whether fragments are referenced, never validates their contentsFragment definitions are only validated via
validate_fragment_definition, which is only reachable throughvalidate_fragment_spread— i.e., a fragment spread in an operation's selection set. Orphan fragments never enter this path.Expected behavior
Directive arguments (and other fragment-level validation) should be reported regardless of whether the fragment is used in an operation.
Possible approaches
Always validate all fragment definitions: In
validate_with_or_without_schema(orvalidate_executable_document), iteratedocument.fragmentsdirectly and callvalidate_fragment_definitionfor each, independent of reachability from operations. This is the simplest fix but changes the existing behavior for all callers.Configurable validation via an option: Add an option to
ExecutableDocument::validate(or a new method) that controls whether unused fragments receive full validation. This would let LSP tooling opt in without affecting the default behavior for spec-strict use cases.Addressed as part of
ExecutableDocumentBuilder(Add fragments toexecutable_doc.validate()#1004 / feat(compiler): IntroduceExecutableDocumentBuilderfor operations with multiple sources #1017): The builder already needs to handle multi-source fragments. Validation of independently-defined fragments could be a natural part of that API, where the notion of "unused" doesn't apply in the same way.Related: #1004, #988