From 36e00c90a553efebca19ad164f5bea4460173aee Mon Sep 17 00:00:00 2001 From: Fred Zhang Date: Mon, 9 Mar 2026 18:52:45 -0700 Subject: [PATCH] feat(validator): handle repeatable directives correctly Fixes a panic when validating directives that are not defined in the schema. Previously, the UniqueDirectivesPerLocation rule would panic if a directive did not have a definition, as it tried to access . This change adds a nil check for before accessing . A directive is considered non-repeatable if its definition is not found or if its definition explicitly states it is not repeatable. Added test cases for: - A custom repeatable directive used multiple times (expected no error). - A custom non-repeatable directive used multiple times (expected error). --- .../UniqueDirectivesPerLocationRule.spec.yml | 28 +++++++++++++++++++ .../rules/unique_directives_per_location.go | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/validator/imported/spec/UniqueDirectivesPerLocationRule.spec.yml b/validator/imported/spec/UniqueDirectivesPerLocationRule.spec.yml index 50903ad3..e75d9270 100644 --- a/validator/imported/spec/UniqueDirectivesPerLocationRule.spec.yml +++ b/validator/imported/spec/UniqueDirectivesPerLocationRule.spec.yml @@ -141,3 +141,31 @@ locations: - {line: 3, column: 15} - {line: 3, column: 26} +- name: custom repeatable directives in same location + rule: UniqueDirectivesPerLocation + schema: | + directive @customRepeatable repeatable on FIELD + type Query { + field: String + } + query: | + { + field @customRepeatable @customRepeatable + } + errors: [] +- name: duplicate custom non-repeatable directives in one location + rule: UniqueDirectivesPerLocation + schema: | + directive @customNonRepeatable on FIELD + type Query { + field: String + } + query: | + { + field @customNonRepeatable @customNonRepeatable + } + errors: + - message: The directive "@customNonRepeatable" can only be used once at this location. + locations: + - {line: 2, column: 13} + - {line: 2, column: 35} diff --git a/validator/rules/unique_directives_per_location.go b/validator/rules/unique_directives_per_location.go index a1a01016..b801ede3 100644 --- a/validator/rules/unique_directives_per_location.go +++ b/validator/rules/unique_directives_per_location.go @@ -13,7 +13,7 @@ var UniqueDirectivesPerLocationRule = Rule{ seen := map[string]bool{} for _, dir := range directives { - if dir.Name != "repeatable" && seen[dir.Name] { + if (dir.Definition == nil || !dir.Definition.IsRepeatable) && seen[dir.Name] { addError( Message( `The directive "@%s" can only be used once at this location.`,