go-kratos/kratos · warning

%q is not a valid value

Error message

%q is not a valid value

What it means

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.

Source

Thrown at encoding/form/proto_decode.go:177

	case protoreflect.BoolKind:
		v, err := strconv.ParseBool(value)
		if err != nil {
			return protoreflect.Value{}, err
		}
		return protoreflect.ValueOfBool(v), nil
	case protoreflect.EnumKind:
		enum, err := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName())
		switch {
		case errors.Is(err, protoregistry.NotFound):
			return protoreflect.Value{}, fmt.Errorf("enum %q is not registered", fd.Enum().FullName())
		case err != nil:
			return protoreflect.Value{}, fmt.Errorf("failed to look up enum: %w", err)
		}
		v := enum.Descriptor().Values().ByName(protoreflect.Name(value))
		if v == nil {
			i, err := strconv.ParseInt(value, 10, 32) //nolint:mnd
			if err != nil {
				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value)
			}
			v = enum.Descriptor().Values().ByNumber(protoreflect.EnumNumber(i))
			if v == nil {
				return protoreflect.Value{}, fmt.Errorf("%q is not a valid value", value)
			}
		}
		return protoreflect.ValueOfEnum(v.Number()), nil
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		v, err := strconv.ParseInt(value, 10, 32) //nolint:mnd
		if err != nil {
			return protoreflect.Value{}, err
		}
		return protoreflect.ValueOfInt32(int32(v)), nil
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		v, err := strconv.ParseInt(value, 10, 64) //nolint:mnd
		if err != nil {
			return protoreflect.Value{}, err
		}

View on GitHub (pinned to 668db92c2c)

Solutions

  1. Send the exact proto value name (case-sensitive, e.g. ACTIVE) or its integer number (e.g. 1)
  2. Expose the accepted names via OpenAPI/protobuf docs or a validation endpoint so frontend uses exact tokens
  3. Add client-side whitelisting of enum values before encoding them into the request
  4. 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)

Example fix

// enum Status { STATUS_UNSPECIFIED = 0; ACTIVE = 1; INACTIVE = 2; }
// before: GET /x?status=active -> "active" is not a valid value
// after:  GET /x?status=ACTIVE   (or ?status=1)
Defensive patterns

Strategy: validation

Validate before calling

// Whitelist exact enum value names (case-sensitive) before sending
var validStatus = map[string]bool{"ACTIVE": true, "INACTIVE": true}
func okEnum(value string) bool { return validStatus[value] }

Type guard

func isValidEnumValue(fd protoreflect.FieldDescriptor, s string) bool {
	if fd.Kind() != protoreflect.EnumKind {
		return true
	}
	if fd.Enum().Values().ByName(protoreflect.Name(s)) != nil {
		return true
	}
	n, err := strconv.ParseInt(s, 10, 32)
	return err == nil && fd.Enum().Values().ByNumber(protoreflect.EnumNumber(n)) != nil
}

Try / catch

if err := binding.BindQuery(msg, q); err != nil {
	if strings.Contains(err.Error(), "is not a valid value") {
		return errors.BadRequest("BAD_ENUM", err.Error()) // echo the accepted names in your error catalog
	}
}

Prevention

When it happens

Trigger: `?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.

Common situations: 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.

Related errors


AI-assisted analysis of go-kratos/kratos@668db92c2c (2026-08-16). Data as JSON: /api/errors/6e1ec20cca37860f. Report an issue: GitHub.