go-kratos/kratos · warning

parsing field %q: %w

Error message

parsing field %q: %w

What it means

Form-binding decoder error wrapping the underlying strconv/parse failure for a singular field: parseField() could not convert the submitted string into the field's proto kind (bool, int32/64, uint32/64, float, enum, bytes base64, Duration, etc.). The %w chain preserves the original strconv error, so errors.Is/errors.As on strconv.NumError works.

Source

Thrown at encoding/form/proto_decode.go:123

	}
	return fd
}

func getDescriptorByFieldAndName(fields protoreflect.FieldDescriptors, fieldName string) protoreflect.FieldDescriptor {
	var fd protoreflect.FieldDescriptor
	if fd = fields.ByName(protoreflect.Name(fieldName)); fd == nil {
		fd = fields.ByJSONName(fieldName)
	}
	return fd
}

func populateField(fd protoreflect.FieldDescriptor, v protoreflect.Message, value string) error {
	if value == "" {
		return nil
	}
	val, err := parseField(fd, value)
	if err != nil {
		return fmt.Errorf("parsing field %q: %w", fd.FullName().Name(), err)
	}
	v.Set(fd, val)
	return nil
}

func populateRepeatedField(fd protoreflect.FieldDescriptor, list protoreflect.List, values []string) error {
	for _, value := range values {
		v, err := parseField(fd, value)
		if err != nil {
			return fmt.Errorf("parsing list %q: %w", fd.FullName().Name(), err)
		}
		list.Append(v)
	}
	return nil
}

func populateMapField(fd protoreflect.FieldDescriptor, mp protoreflect.Map, fieldPath []string, values []string) error {
	_, keyName, err := parseURLQueryMapKey(strings.Join(fieldPath, fieldSeparator))

View on GitHub (pinned to 668db92c2c)

Solutions

  1. Read the wrapped strconv error to see expected syntax, then send a value matching the field kind (plain base-10 integers, true/false, dot decimals, Go duration strings for Duration)
  2. Add client-side validation/coercion for query params before building the URL
  3. Strip empty or placeholder values ('null','undefined') from requests instead of sending them
  4. For bytes fields, ensure standard base64 (or URL-safe base64, both accepted) with correct padding
  5. Log the offending field name from the error during development to pinpoint which param is malformed

Example fix

// proto: int32 limit = 1;
// before: GET /search?limit=%22ten%22 -> parsing field "limit": strconv.ParseInt: parsing "ten": invalid syntax
// after:  GET /search?limit=10
Defensive patterns

Strategy: validation

Validate before calling

// Client-side type check of params against the proto before building the URL
func validateTyped(q url.Values, typed map[string]func(string) error) error {
	for k, check := range typed {
		for _, val := range q[k] {
			if err := check(val); err != nil {
				return fmt.Errorf("param %s=%q: %w", k, val, err)
			}
	}
	}
	return nil
}
// usage: validateTyped(q, map[string]func(string) error{
//   "limit": func(s string) error { _, e := strconv.ParseInt(s,10,32); return e },
//   "active": func(s string) error { _, e := strconv.ParseBool(s); return e },
// })

Try / catch

if err := binding.BindQuery(msg, q); err != nil {
	var numErr *strconv.NumError
	if strings.Contains(err.Error(), "parsing field") && errors.As(err, &numErr) {
		return errors.BadRequest("BAD_PARAM", numErr.Func+" failed for "+numErr.Num)
	}
	return err
}

Prevention

When it happens

Trigger: Type-mismatched values for a scalar field: `?count=abc` for int32, `?flag=yes` for bool in locales/builders that emit yes/no, `?ratio=1,5` (comma decimal) for float, `?blob=!!!` for a BytesValue (bad base64), `?t=3x` for a Duration field (time.ParseDuration syntax required).

Common situations: Frontend sending localized number formats; null/undefined stringified into the query ('null' for an int); missing client-side validation; units appended to numeric values ('10px', '5s' on an int field); base64 padding stripped by URL transmission for bytes fields.

Related errors


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