{"record":{"id":"c560762fbe6ba70a","repo":"gofiber/fiber","slug":"logger-tag-name-and-function-are-required","errorCode":null,"errorMessage":"logger: tag name and function are required","messagePattern":"logger: tag name and function are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/logger/tags.go","lineNumber":57,"sourceCode":"\tTagRespHeader        = \"respHeader:\"\n\tTagLocals            = \"locals:\"\n\tTagQuery             = \"query:\"\n\tTagForm              = \"form:\"\n\tTagCookie            = \"cookie:\"\n\tTagBlack             = \"black\"\n\tTagRed               = \"red\"\n\tTagGreen             = \"green\"\n\tTagYellow            = \"yellow\"\n\tTagBlue              = \"blue\"\n\tTagMagenta           = \"magenta\"\n\tTagCyan              = \"cyan\"\n\tTagWhite             = \"white\"\n\tTagReset             = \"reset\"\n)\n\n// ErrTagInvalid is returned by RegisterTag and panicked from MustRegisterTag\n// when the supplied tag name or renderer is empty.\nvar ErrTagInvalid = errors.New(\"logger: tag name and function are required\")\n\nvar registeredTags = struct {\n\tm map[string]LogFunc\n\tsync.RWMutex\n}{\n\tm: make(map[string]LogFunc),\n}\n\n// RegisterTag registers a global logger middleware tag.\n// Registered tags are available to logger middleware instances created after\n// registration and can be overridden per instance with Config.CustomTags.\n// Re-registering a tag replaces the existing tag function.\nfunc RegisterTag(tag string, fn LogFunc) error {\n\tif tag == \"\" || fn == nil {\n\t\treturn ErrTagInvalid\n\t}\n\n\tregisteredTags.Lock()","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/logger/tags.go#L39-L75","documentation":"Returned by middleware/logger.RegisterTag (and panicked from MustRegisterTag) when the tag name is empty or the renderer function is nil. Registration replaces existing tags, so both inputs must be valid before the map is mutated. The guard runs first, before acquiring the lock.","triggerScenarios":"Calling RegisterTag(\"\", fn), RegisterTag(name, nil), or MustRegisterTag with either invalid argument. Common when tag names are generated dynamically and an entry is missing.","commonSituations":"Building tag registrations from a config map where one entry has an empty key or a nil function; refactoring that left a nil LogFunc; a loop that registers tags but skips setting fn for some.","solutions":["Provide a non-empty tag name and a non-nil LogFunc to RegisterTag.","If registering from a map, skip or reject entries with empty keys or nil functions before calling RegisterTag.","Use RegisterTag (not MustRegisterTag) when inputs come from untrusted/config sources so a bad entry is an error, not a panic."],"exampleFix":"// before\nlogger.MustRegisterTag(name, nilFn) // panics\n// after\nif name != \"\" && fn != nil {\n    logger.RegisterTag(name, fn)\n}","handlingStrategy":"validation","validationCode":"if name == \"\" || fn == nil {\n    return logger.ErrTagInvalid\n}","typeGuard":null,"tryCatchPattern":"if err := logger.RegisterTag(name, fn); err != nil {\n    if errors.Is(err, logger.ErrTagInvalid) {\n        // skip this entry; name or fn was empty\n    }\n}","preventionTips":["Filter empty keys and nil functions before bulk-registering from a map.","Prefer RegisterTag over MustRegisterTag when inputs come from config.","Unit-test registration paths with both invalid inputs."],"tags":["logger","config","template"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}