{"record":{"id":"633ee2a6657c05f8","repo":"geektutu/7days-golang","slug":"rpc-service-already-defined-633ee2","errorCode":null,"errorMessage":"rpc: service already defined: ","messagePattern":"rpc: service already defined: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day7-registry/server.go","lineNumber":223,"sourceCode":"\t\t}\n\t\tgo server.ServeConn(conn)\n\t}\n}\n\n// Accept accepts connections on the listener and serves requests\n// for each incoming connection.\nfunc Accept(lis net.Listener) { DefaultServer.Accept(lis) }\n\n// Register publishes in the server the set of methods of the\n// receiver value that satisfy the following conditions:\n//\t- exported method of exported type\n//\t- two arguments, both of exported type\n//\t- the second argument is a pointer\n//\t- one return value, of type error\nfunc (server *Server) Register(rcvr interface{}) error {\n\ts := newService(rcvr)\n\tif _, dup := server.serviceMap.LoadOrStore(s.name, s); dup {\n\t\treturn errors.New(\"rpc: service already defined: \" + s.name)\n\t}\n\treturn nil\n}\n\n// Register publishes the receiver's methods in the DefaultServer.\nfunc Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }\n\nconst (\n\tconnected        = \"200 Connected to Gee RPC\"\n\tdefaultRPCPath   = \"/_geeprc_\"\n\tdefaultDebugPath = \"/debug/geerpc\"\n)\n\n// ServeHTTP implements an http.Handler that answers RPC requests.\nfunc (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {\n\tif req.Method != \"CONNECT\" {\n\t\tw.Header().Set(\"Content-Type\", \"text/plain; charset=utf-8\")\n\t\tw.WriteHeader(http.StatusMethodNotAllowed)","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day7-registry/server.go#L205-L241","documentation":"Server.Register stores the receiver by its derived name in serviceMap using LoadOrStore; if a service with that name is already registered it returns this error instead of overwriting. Duplicate registration is refused to keep one canonical implementation per service name.","triggerScenarios":"Calling Register twice with the same receiver type (or two types whose derived name collides, e.g. value and pointer of the same type) on the same Server, or registering in code that runs on each reconnect/restart within the same process.","commonSituations":"Registration placed in a hot path or init function invoked multiple times; registering both Foo and *Foo; tests constructing one server but calling Register in setup run repeatedly.","solutions":["Call Register only once per service per Server instance (e.g. at startup/init)","Guard registration with sync.Once or check whether the service is already registered","Register a single instance and reuse it instead of re-registering per connection","If you genuinely need a new implementation, create a new Server or use a distinct type name"],"exampleFix":"// before\nfunc onConn(s *geerpc.Server) { s.Register(new(Foo)) } // called per connection\n// after\nvar once sync.Once\nfunc setup(s *geerpc.Server) { once.Do(func() { s.Register(new(Foo)) }) }","handlingStrategy":"try-catch","validationCode":"// register once per process\nvar registerOnce sync.Once\nfunc ensureRegistered(s *geerpc.Server) {\n    registerOnce.Do(func() {\n        if err := s.Register(new(Foo)); err != nil {\n            if strings.Contains(err.Error(), \"already defined\") { return } // idempotent\n            log.Fatal(err)\n        }\n    })\n}","typeGuard":null,"tryCatchPattern":"if err := srv.Register(new(Foo)); err != nil {\n    if strings.Contains(err.Error(), \"already defined\") {\n        return nil // treat as idempotent success\n    }\n    return err\n}","preventionTips":["Register services only once, at startup, not per connection/request","Do not register both a value and a pointer of the same type","Treat duplicate registration as an idempotent no-op in setup code"],"tags":["go","rpc","registration","duplicate"],"backgroundTag":"rpc-service-already-registered","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}