{"record":{"id":"93961422598113d6","repo":"go-kratos/kratos","slug":"no-field-path","errorCode":null,"errorMessage":"no field path","messagePattern":"no field path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"info","filePath":"encoding/form/proto_decode.go","lineNumber":39,"sourceCode":")\n\nconst fieldSeparator = \".\"\n\nvar errInvalidFormatMapKey = errors.New(\"invalid formatting for map key\")\n\n// DecodeValues decode url value into proto message.\nfunc DecodeValues(msg proto.Message, values url.Values) error {\n\tfor key, values := range values {\n\t\tif err := populateFieldValues(msg.ProtoReflect(), strings.Split(key, \".\"), values); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc populateFieldValues(v protoreflect.Message, fieldPath []string, values []string) error {\n\tif len(fieldPath) < 1 {\n\t\treturn errors.New(\"no field path\")\n\t}\n\tif len(values) < 1 {\n\t\treturn errors.New(\"no value provided\")\n\t}\n\n\tvar fd protoreflect.FieldDescriptor\n\tfor i, fieldName := range fieldPath {\n\t\tif fd = getFieldDescriptor(v, fieldName); fd == nil {\n\t\t\t// ignore unexpected field.\n\t\t\treturn nil\n\t\t}\n\t\tif fd.IsMap() && len(fieldPath) == 2 {\n\t\t\treturn populateMapField(fd, v.Mutable(fd).Map(), fieldPath, values)\n\t\t}\n\t\tif i == len(fieldPath)-1 {\n\t\t\tbreak\n\t\t}\n\t\tif fd.Message() == nil || fd.Cardinality() == protoreflect.Repeated {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/go-kratos/kratos/blob/668db92c2c001e9552594ba5a8aede8456af6d7e/encoding/form/proto_decode.go#L21-L57","documentation":"'no field path' (encoding/form/proto_decode.go:39) is a defensive guard at the top of populateFieldValues: it fires when fieldPath has fewer than one element. In the public entry point DecodeValues, keys are built with strings.Split(key, \".\") which always returns at least one element (even for the empty string you get [\"\"]), and the internal recursions pass fieldPath[1:] only from paths of length >= 2 or the fixed []string{fieldPath[1]}. So through supported API surface this error is effectively unreachable; hitting it means the unexported helper was called with an empty slice (forks, tests, or refactors of the package).","triggerScenarios":"Direct internal invocation populateFieldValues(msg, []string{}, values) in modified/forked copies of encoding/form; a refactor that introduces a trimming step producing an empty path slice; goptest plumbing that calls the unexported function via package-internal tests.","commonSituations":"Vendored/forked kratos form codec modified locally; custom query-key preprocessing inserted before populateFieldValues that can return zero segments; version drift where a caller contract changed but this guard stayed.","solutions":["If you forked or reflect into this package, ensure fieldPath always contains at least one segment before calling","In public usage, treat this error as a bug report - file it upstream with the exact query that produced it","Audit any local preprocessing of query keys (splitting, trimming) so it never yields an empty slice"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// guard any local preprocessing before calling the codec\nif len(segments) == 0 {\n    return fmt.Errorf(\"empty field path from key %q\", rawKey)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not fork/reflect into encoding/form internals; use DecodeValues only","If you preprocess query keys, assert the split result is non-empty","Report occurrences upstream with the exact input - through public API it should be impossible"],"tags":["encoding","form","proto","internal","defensive-check"],"backgroundTag":null,"analyzedSha":"668db92c2c001e9552594ba5a8aede8456af6d7e","analyzedAt":"2026-08-16T02:07:20.704Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}