{"record":{"id":"6e1ec20cca37860f","repo":"go-kratos/kratos","slug":"q-is-not-a-valid-value","errorCode":null,"errorMessage":"%q is not a valid value","messagePattern":"%q is not a valid value","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"encoding/form/proto_decode.go","lineNumber":177,"sourceCode":"\tcase protoreflect.BoolKind:\n\t\tv, err := strconv.ParseBool(value)\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfBool(v), nil\n\tcase protoreflect.EnumKind:\n\t\tenum, err := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName())\n\t\tswitch {\n\t\tcase errors.Is(err, protoregistry.NotFound):\n\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"enum %q is not registered\", fd.Enum().FullName())\n\t\tcase err != nil:\n\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"failed to look up enum: %w\", err)\n\t\t}\n\t\tv := enum.Descriptor().Values().ByName(protoreflect.Name(value))\n\t\tif v == nil {\n\t\t\ti, err := strconv.ParseInt(value, 10, 32) //nolint:mnd\n\t\t\tif err != nil {\n\t\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"%q is not a valid value\", value)\n\t\t\t}\n\t\t\tv = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i))\n\t\t\tif v == nil {\n\t\t\t\treturn protoreflect.Value{}, fmt.Errorf(\"%q is not a valid value\", value)\n\t\t\t}\n\t\t}\n\t\treturn protoreflect.ValueOfEnum(v.Number()), nil\n\tcase protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:\n\t\tv, err := strconv.ParseInt(value, 10, 32) //nolint:mnd\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}\n\t\treturn protoreflect.ValueOfInt32(int32(v)), nil\n\tcase protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:\n\t\tv, err := strconv.ParseInt(value, 10, 64) //nolint:mnd\n\t\tif err != nil {\n\t\t\treturn protoreflect.Value{}, err\n\t\t}","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/encoding/form/proto_decode.go#L159-L195","documentation":"Form-binding decoder error for enum fields at proto_decode.go:177: the submitted string did not match any enum value name (enum.Descriptor().Values().ByName returned nil), and the fallback strconv.ParseInt of the string also failed - so the value is neither a known enum value name nor a numeric enum number at all. A correcting nuance: name matching is case-sensitive against the proto value names.","triggerScenarios":"`?status=Active` (wrong case; proto value is ACTIVE), `?status=in_progress` where the proto name is IN_PROGRESS, `?status=y` for a bool-ish enum, or arbitrary strings like `?status=hello` for enum fields. Distinct from error 54: here the string is not even parseable as an integer, so it can only be a bad name.","commonSituations":"Frontends sending humanized/lowercase labels instead of proto value names; localized status strings; typos after proto renames; enums whose proto names carry a project prefix (STATE_ACTIVE) that clients drop.","solutions":["Send the exact proto value name (case-sensitive, e.g. ACTIVE) or its integer number (e.g. 1)","Expose the accepted names via OpenAPI/protobuf docs or a validation endpoint so frontend uses exact tokens","Add client-side whitelisting of enum values before encoding them into the request","If users must type friendly labels, map them server-side to proto names before form binding (decode into a string, convert, then set the enum)"],"exampleFix":"// enum Status { STATUS_UNSPECIFIED = 0; ACTIVE = 1; INACTIVE = 2; }\n// before: GET /x?status=active -> \"active\" is not a valid value\n// after:  GET /x?status=ACTIVE   (or ?status=1)","handlingStrategy":"validation","validationCode":"// Whitelist exact enum value names (case-sensitive) before sending\nvar validStatus = map[string]bool{\"ACTIVE\": true, \"INACTIVE\": true}\nfunc okEnum(value string) bool { return validStatus[value] }","typeGuard":"func isValidEnumValue(fd protoreflect.FieldDescriptor, s string) bool {\n\tif fd.Kind() != protoreflect.EnumKind {\n\t\treturn true\n\t}\n\tif fd.Enum().Values().ByName(protoreflect.Name(s)) != nil {\n\t\treturn true\n\t}\n\tn, err := strconv.ParseInt(s, 10, 32)\n\treturn err == nil && fd.Enum().Values().ByNumber(protoreflect.EnumNumber(n)) != nil\n}","tryCatchPattern":"if err := binding.BindQuery(msg, q); err != nil {\n\tif strings.Contains(err.Error(), \"is not a valid value\") {\n\t\treturn errors.BadRequest(\"BAD_ENUM\", err.Error()) // echo the accepted names in your error catalog\n\t}\n}","preventionTips":["Send exact proto value names (UPPER_SNAKE, case-sensitive) or raw numbers","Generate client enum constants from the proto instead of hand-writing strings","Publish accepted values per endpoint in docs/OpenAPI and keep them generated","Map user-facing labels to proto names server-side before binding"],"tags":["go","kratos","form-binding","protobuf","enum","validation"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}