{"record":{"id":"7ae332e097e791ec","repo":"go-kratos/kratos","slug":"parsing-field-q-w","errorCode":null,"errorMessage":"parsing field %q: %w","messagePattern":"parsing field %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"encoding/form/proto_decode.go","lineNumber":123,"sourceCode":"\t}\n\treturn fd\n}\n\nfunc getDescriptorByFieldAndName(fields protoreflect.FieldDescriptors, fieldName string) protoreflect.FieldDescriptor {\n\tvar fd protoreflect.FieldDescriptor\n\tif fd = fields.ByName(protoreflect.Name(fieldName)); fd == nil {\n\t\tfd = fields.ByJSONName(fieldName)\n\t}\n\treturn fd\n}\n\nfunc populateField(fd protoreflect.FieldDescriptor, v protoreflect.Message, value string) error {\n\tif value == \"\" {\n\t\treturn nil\n\t}\n\tval, err := parseField(fd, value)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing field %q: %w\", fd.FullName().Name(), err)\n\t}\n\tv.Set(fd, val)\n\treturn nil\n}\n\nfunc populateRepeatedField(fd protoreflect.FieldDescriptor, list protoreflect.List, values []string) error {\n\tfor _, value := range values {\n\t\tv, err := parseField(fd, value)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"parsing list %q: %w\", fd.FullName().Name(), err)\n\t\t}\n\t\tlist.Append(v)\n\t}\n\treturn nil\n}\n\nfunc populateMapField(fd protoreflect.FieldDescriptor, mp protoreflect.Map, fieldPath []string, values []string) error {\n\t_, keyName, err := parseURLQueryMapKey(strings.Join(fieldPath, fieldSeparator))","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/encoding/form/proto_decode.go#L105-L141","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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)","Add client-side validation/coercion for query params before building the URL","Strip empty or placeholder values ('null','undefined') from requests instead of sending them","For bytes fields, ensure standard base64 (or URL-safe base64, both accepted) with correct padding","Log the offending field name from the error during development to pinpoint which param is malformed"],"exampleFix":"// proto: int32 limit = 1;\n// before: GET /search?limit=%22ten%22 -> parsing field \"limit\": strconv.ParseInt: parsing \"ten\": invalid syntax\n// after:  GET /search?limit=10","handlingStrategy":"validation","validationCode":"// Client-side type check of params against the proto before building the URL\nfunc validateTyped(q url.Values, typed map[string]func(string) error) error {\n\tfor k, check := range typed {\n\t\tfor _, val := range q[k] {\n\t\t\tif err := check(val); err != nil {\n\t\t\t\treturn fmt.Errorf(\"param %s=%q: %w\", k, val, err)\n\t\t\t}\n\t}\n\t}\n\treturn nil\n}\n// usage: validateTyped(q, map[string]func(string) error{\n//   \"limit\": func(s string) error { _, e := strconv.ParseInt(s,10,32); return e },\n//   \"active\": func(s string) error { _, e := strconv.ParseBool(s); return e },\n// })","typeGuard":null,"tryCatchPattern":"if err := binding.BindQuery(msg, q); err != nil {\n\tvar numErr *strconv.NumError\n\tif strings.Contains(err.Error(), \"parsing field\") && errors.As(err, &numErr) {\n\t\treturn errors.BadRequest(\"BAD_PARAM\", numErr.Func+\" failed for \"+numErr.Num)\n\t}\n\treturn err\n}","preventionTips":["Never stringify null/undefined into query values; omit the key instead","Standardize on base-10 integers, true/false booleans, dot decimals in all generated clients","For Duration fields send Go duration strings (300ms, 2h45m) which time.ParseDuration accepts","Add a client-side schema validator (generated from proto) in frontends before requests"],"tags":["go","kratos","form-binding","protobuf","strconv","validation"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}