From 0e38e421c92d10cc922cf6c5baa6027684cb8fd0 Mon Sep 17 00:00:00 2001 From: Marcin Romaszewicz Date: Sat, 20 Jun 2026 22:03:12 -0700 Subject: [PATCH] Don't emit enum constants for array-typed schemas A schema that combines `type: array` with an `enum` is malformed: the enum members are scalars, not arrays, so no array value could ever satisfy the constraint. In the wild this shows up as the item enum being copied onto the array (e.g. Jellyfin's `TranscodingInfo.TranscodeReasons` in issue #2176). oapi-codegen took the enum branch purely on `len(schema.Enum) > 0`, emitting typed constants while the Go type resolved from `type: array` to a slice. That produced `const X SliceType = ...`, which is not a valid Go constant type: type TranscodingInfoTranscodeReasons []TranscodeReason const TranscodingInfoTranscodeReasonsAnamorphicVideoNotSupported \ TranscodingInfoTranscodeReasons = ... // invalid constant type Guard the enum branch with `!t.Is("array")` so array-typed schemas fall through to normal array handling and generate as a plain `[]ItemType`. The meaningful enum lives on the item schema, which still gets its own constants. No existing fixtures change. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/codegen/schema.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pkg/codegen/schema.go b/pkg/codegen/schema.go index 930e2b59e..c109e54a5 100644 --- a/pkg/codegen/schema.go +++ b/pkg/codegen/schema.go @@ -970,7 +970,16 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) { } return outSchema, nil - } else if len(schema.Enum) > 0 || (globalState.is31 && schema.Const != nil) { + } else if (len(schema.Enum) > 0 || (globalState.is31 && schema.Const != nil)) && !t.Is("array") { + // An `enum` (or 3.1 `const`) is only meaningful on a scalar schema: + // it constrains a single value, which we render as a typed constant. + // A schema that combines `type: array` with an `enum` is malformed -- + // the enum members are scalars, not arrays, so no array value could + // satisfy it (seen in the wild as a copy of the item enum onto the + // array; see issue #2176). Emitting constants there yields + // `const X SliceType = ...`, which is not a valid Go constant type. + // Fall through to normal array handling so the schema generates as a + // plain `[]ItemType`; the item schema carries the real enum. err := oapiSchemaToGoType(schema, path, &outSchema) // Enums need to be typed, so that the values aren't interchangeable, // so no matter what schema conversion thinks, we need to define a