{"record":{"id":"38d909987948d804","repo":"micro/go-micro","slug":"reflection-list-services-returned-t","errorCode":null,"errorMessage":"reflection list services returned %T","messagePattern":"reflection list services returned %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gateway/mcp/grpcreflect.go","lineNumber":126,"sourceCode":"\treturn out, nil\n}\n\nfunc loadReflectedFiles(ctx context.Context, conn *grpc.ClientConn) (*protoregistryFiles, []string, error) {\n\tclient := reflectionpb.NewServerReflectionClient(conn)\n\tstream, err := client.ServerReflectionInfo(ctx)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif err := stream.Send(&reflectionpb.ServerReflectionRequest{MessageRequest: &reflectionpb.ServerReflectionRequest_ListServices{ListServices: \"\"}}); err != nil {\n\t\treturn nil, nil, err\n\t}\n\tresp, err := stream.Recv()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tlist := resp.GetListServicesResponse()\n\tif list == nil {\n\t\treturn nil, nil, fmt.Errorf(\"reflection list services returned %T\", resp.MessageResponse)\n\t}\n\n\tset := &descriptorpb.FileDescriptorSet{}\n\tseen := map[string]bool{}\n\tvar services []string\n\tfor _, svc := range list.Service {\n\t\tname := svc.Name\n\t\tif strings.HasPrefix(name, \"grpc.reflection.\") {\n\t\t\tcontinue\n\t\t}\n\t\tservices = append(services, name)\n\t\tif err := requestFileContainingSymbol(ctx, client, name, set, seen); err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\tfiles, err := newProtoregistryFiles(set)\n\tif err != nil {\n\t\treturn nil, nil, err","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/gateway/mcp/grpcreflect.go#L108-L144","documentation":"loadReflectedFiles expects the first message on the reflection stream to be a ListServicesResponse. If the server reflection response carries a different MessageResponse variant (e.g. an ErrorResponse or FileDescriptorResponse), this type-mismatch error is returned, naming the unexpected Go type received.","triggerScenarios":"requesting service listing via the ServerReflectionInfo stream and stream.Recv() returns a response whose GetListServicesResponse() is nil — the server answered with another message type instead of the list.","commonSituations":"A server behind a proxy mangling reflection responses; a server returning ErrorResponse for the LIST_SERVICES request (e.g. reflection partially disabled); version skew between reflection protocol implementations.","solutions":["Log the received %T to see which response variant came back (most likely ErrorResponse) and handle its message.","Ensure the target supports the LIST_SERVICES reflection request (reflection.Register on the server).","Check the server's reflection/grpc version and upgrade mismatched clients/servers.","Inspect any proxy between client and server that could alter reflection responses."],"exampleFix":"// before (server)\n// reflection partially wired; handler returns error for list\n// after (server)\nreflection.Register(server) // guarantees ListServicesResponse for LIST_SERVICES","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func asListServices(resp *refpb.ServerReflectionResponse) *refpb.ListServicesResponse {\n    if list := resp.GetListServicesResponse(); list != nil {\n        return list\n    }\n    if errResp := resp.GetErrorResponse(); errResp != nil {\n        log.Printf(\"reflection list failed: %s\", errResp.GetErrorText())\n    }\n    return nil\n}","tryCatchPattern":"if list == nil {\n    if e := resp.GetErrorResponse(); e != nil {\n        return fmt.Errorf(\"reflection list error from server: %s\", e.GetErrorText())\n    }\n    return fmt.Errorf(\"reflection list services returned %T\", resp.MessageResponse)\n}","preventionTips":["Handle the ErrorResponse variant explicitly instead of assuming ListServicesResponse.","Keep server reflection implementations up to date with the protocol.","Log unexpected %T values to diagnose proxy interference.","Test reflection against each server version in your fleet."],"tags":["grpc","reflection","protocol-mismatch","type-error"],"backgroundTag":"grpc-reflection-unexpected-response","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}