diff --git a/pkg/parser/schema_errors.go b/pkg/parser/schema_errors.go index b3e9d9ac635..00868f3c2ba 100644 --- a/pkg/parser/schema_errors.go +++ b/pkg/parser/schema_errors.go @@ -3,6 +3,7 @@ package parser import ( "fmt" "regexp" + "sort" "strings" ) @@ -211,9 +212,7 @@ func rewriteAdditionalPropertiesError(message string) string { match := re.FindStringSubmatch(message) if len(match) >= 2 { - properties := match[1] - // Clean up the property list and make it more readable - properties = strings.ReplaceAll(properties, "'", "") + properties := normalizeAdditionalPropertyList(match[1]) if strings.Contains(properties, ",") { return "Unknown properties: " + properties @@ -225,3 +224,17 @@ func rewriteAdditionalPropertiesError(message string) string { return message } + +func normalizeAdditionalPropertyList(raw string) string { + raw = strings.ReplaceAll(raw, "'", "") + parts := strings.Split(raw, ",") + cleaned := make([]string, 0, len(parts)) + for _, part := range parts { + trimmed := strings.TrimSpace(part) + if trimmed != "" { + cleaned = append(cleaned, trimmed) + } + } + sort.Strings(cleaned) + return strings.Join(cleaned, ", ") +} diff --git a/pkg/parser/schema_errors_test.go b/pkg/parser/schema_errors_test.go index 62e1c397c92..37608a391e4 100644 --- a/pkg/parser/schema_errors_test.go +++ b/pkg/parser/schema_errors_test.go @@ -274,3 +274,34 @@ func TestTranslateSchemaConstraintMessage(t *testing.T) { }) } } + +func TestRewriteAdditionalPropertiesErrorOrdering(t *testing.T) { + tests := []struct { + name string + in string + want string + }{ + { + name: "sorts multiple unknown properties", + in: "at '/safe-outputs': additional properties 'zeta', 'alpha', 'beta' not allowed", + want: "Unknown properties: alpha, beta, zeta", + }, + { + name: "sorts and trims unquoted list", + in: "additional properties zeta, alpha, beta not allowed", + want: "Unknown properties: alpha, beta, zeta", + }, + { + name: "single unknown property remains singular", + in: "additional property 'timeout_minutes' not allowed", + want: "Unknown property: timeout_minutes", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := rewriteAdditionalPropertiesError(tt.in) + assert.Equal(t, tt.want, got) + }) + } +}