grpc-ecosystem/grpc-gateway · error
not an aggregate type: %s in %s
Error message
not an aggregate type: %s in %s
What it means
Path-traversal error from Registry.resolveFieldPath: while walking a dotted field path, an intermediate component resolved to a non-message field (scalar/enum), yet more path components follow. Only message/group fields can be descended into, so the path like 'scalar_field.sub' is invalid; the error names the offending field and full path.
Source
Thrown at internal/descriptor/services.go:337
func (r *Registry) resolveFieldPath(msg *Message, path string, isPathParam bool) ([]FieldPathComponent, error) {
if path == "" {
return nil, nil
}
root := msg
var result []FieldPathComponent
for i, c := range strings.Split(path, ".") {
if i > 0 {
f := result[i-1].Target
switch f.GetType() {
case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_GROUP:
var err error
msg, err = r.LookupMsg(msg.FQMN(), f.GetTypeName())
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("not an aggregate type: %s in %s", f.GetName(), path)
}
}
if grpclog.V(2) {
grpclog.Infof("Lookup %s in %s", c, msg.FQMN())
}
f := lookupField(msg, c)
if f == nil {
return nil, fmt.Errorf("no field %q found in %s", path, root.GetName())
}
result = append(result, FieldPathComponent{Name: c, Target: f})
}
return result, nil
}
View on GitHub (pinned to a58a4436a3)
Solutions
- Remove extra path components after the scalar field, or reorder the path so intermediate components are messages.
- Verify field names and nesting in the HttpRule variable/selector expression.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at internal/descriptor/services.go:337 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02).
Data as JSON: /api/errors/d8cb02327b06a558.
Report an issue: GitHub.