{"record":{"id":"c628ab94c89bfce6","repo":"uber-go/zap","slug":"encoder-already-registered-for-name-q","errorCode":null,"errorMessage":"encoder already registered for name %q","messagePattern":"encoder already registered for name %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"encoder.go","lineNumber":58,"sourceCode":"\t\t},\n\t}\n\t_encoderMutex sync.RWMutex\n)\n\n// RegisterEncoder registers an encoder constructor, which the Config struct\n// can then reference. By default, the \"json\" and \"console\" encoders are\n// registered.\n//\n// Attempting to register an encoder whose name is already taken returns an\n// error.\nfunc RegisterEncoder(name string, constructor func(zapcore.EncoderConfig) (zapcore.Encoder, error)) error {\n\t_encoderMutex.Lock()\n\tdefer _encoderMutex.Unlock()\n\tif name == \"\" {\n\t\treturn errNoEncoderNameSpecified\n\t}\n\tif _, ok := _encoderNameToConstructor[name]; ok {\n\t\treturn fmt.Errorf(\"encoder already registered for name %q\", name)\n\t}\n\t_encoderNameToConstructor[name] = constructor\n\treturn nil\n}\n\nfunc newEncoder(name string, encoderConfig zapcore.EncoderConfig) (zapcore.Encoder, error) {\n\tif encoderConfig.TimeKey != \"\" && encoderConfig.EncodeTime == nil {\n\t\treturn nil, errors.New(\"missing EncodeTime in EncoderConfig\")\n\t}\n\n\t_encoderMutex.RLock()\n\tdefer _encoderMutex.RUnlock()\n\tif name == \"\" {\n\t\treturn nil, errNoEncoderNameSpecified\n\t}\n\tconstructor, ok := _encoderNameToConstructor[name]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"no encoder registered for name %q\", name)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/uber-go/zap/blob/bbd4ecbd8760678fdbac94c93d9aca8069c83b2f/encoder.go#L40-L76","documentation":"RegisterEncoder stores constructors in a global name→constructor map and rejects duplicate registration with fmt.Errorf(\"encoder already registered for name %q\", name) to prevent accidental overwriting of an existing encoder.","triggerScenarios":"Calling zap.RegisterEncoder(\"json\", ctor) or the color-level helpers with a name that already exists (including built-ins \"json\" and \"console\", or a name registered earlier in the process).","commonSituations":"Registering encoders in an init() that runs more than once (e.g. across tests or package re-imports in one binary); re-registering a built-in name; multiple libraries registering the same custom encoder name.","solutions":["Use a unique name, e.g. \"mycompany-json\" instead of \"json\"","Guard with zapcore.EncoderNameExistFunc or check registration once via sync.Once","Remove duplicate init-time registration calls"],"exampleFix":"// before\nerr := zap.RegisterEncoder(\"json\", myCtor) // collides with built-in\n// after\nerr := zap.RegisterEncoder(\"mycompany-json\", myCtor)","handlingStrategy":"try-catch","validationCode":"if err := zap.RegisterEncoder(name, ctor); err != nil {\n    if strings.Contains(err.Error(), \"already registered\") {\n        return nil // idempotent re-registration is fine\n    }\n    return err\n}","typeGuard":null,"tryCatchPattern":"var once sync.Once\nfunc ensureEncoder() error {\n    var err error\n    once.Do(func() { err = zap.RegisterEncoder(\"myencoder\", ctor) })\n    return err\n}","preventionTips":["Register custom encoders under unique, namespaced names","Use sync.Once or init-only registration to avoid duplicates","Never re-register built-in names like \"json\" or \"console\""],"tags":["encoder","registration","duplicate","zap","go"],"backgroundTag":"duplicate-registration","analyzedSha":"bbd4ecbd8760678fdbac94c93d9aca8069c83b2f","analyzedAt":"2026-08-31T13:01:40.228Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}