{"record":{"id":"a1d93af2a0d179c7","repo":"gofiber/fiber","slug":"logger-registercontexttag-requires-a-non-empty-na","errorCode":null,"errorMessage":"logger: RegisterContextTag requires a non-empty name and extractor","messagePattern":"logger: RegisterContextTag requires a non-empty name and extractor","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/logger/context_tag.go","lineNumber":50,"sourceCode":"\t}\n}\n\nfunc emptyLogTag(_ Buffer, _ fiber.Ctx, _ *Data, _ string) (int, error) {\n\treturn 0, nil\n}\n\n// RegisterContextTag registers a string-valued tag in both the logger\n// middleware tag registry and the package-level fiberlog context tag\n// registry, so that the same name can be used in a logger.Config.Format and\n// in fiberlog.SetContextTemplate. extract receives the raw context value\n// (fiber.Ctx, *fasthttp.RequestCtx, or context.Context) and returns the\n// rendered string; an empty return renders nothing.\n//\n// Re-registering a name replaces both renderers. Panics if name is empty or\n// extract is nil — registration is expected at init time.\nfunc RegisterContextTag(name string, extract func(ctx any) string) {\n\tif name == \"\" || extract == nil {\n\t\tpanic(\"logger: RegisterContextTag requires a non-empty name and extractor\")\n\t}\n\n\t// Sanitized like every built-in tag: what extract returns is whatever the\n\t// application pulled out of the context, in practice request data, so writing\n\t// it raw lets a CR or LF close the line and start another.\n\tfiberlog.MustRegisterContextTag(name, func(output fiberlog.Buffer, ctx any, _ *fiberlog.ContextData, _ string) (int, error) {\n\t\tv := extract(ctx)\n\t\tif v == \"\" {\n\t\t\treturn 0, nil\n\t\t}\n\t\treturn logtemplate.WriteSanitizedString(output, v)\n\t})\n\n\tMustRegisterTag(name, func(output Buffer, c fiber.Ctx, _ *Data, _ string) (int, error) {\n\t\tv := extract(c)\n\t\tif v == \"\" {\n\t\t\treturn 0, nil\n\t\t}","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/logger/context_tag.go#L32-L68","documentation":"logger.RegisterContextTag panics when name is empty or the extract callback is nil. Registration is expected to run at init/startup time (MustRegisterTag underneath also panics on bad input), so a malformed call would otherwise silently register nothing and the tag would render empty in logs. The check makes the failure loud.","triggerScenarios":"logger.RegisterContextTag(\"\", extract), logger.RegisterContextTag(\"tenant\", nil), or a dynamically-built name/extractor that evaluates to empty/nil on some code path.","commonSituations":"Looping over a config map to register tags where one entry has an empty name; a helper that returns nil extract when a feature flag is off; copy-paste that drops the extractor argument.","solutions":["Pass a non-empty name and a non-nil extractor: logger.RegisterContextTag(\"tenant\", func(ctx any) string { ... }).","Skip registration conditionally: if name != \"\" && extract != nil { logger.RegisterContextTag(name, extract) }.","Register tags from an init() guarded by a build/runtime check so empty values never reach the call."],"exampleFix":"// before\nlogger.RegisterContextTag(\"\", func(ctx any) string {\n    return ctxValue(ctx)\n})\n\n// after\nlogger.RegisterContextTag(\"tenant\", func(ctx any) string {\n    return ctxValue(ctx)\n})","handlingStrategy":"validation","validationCode":"func registerCtxTag(name string, extract func(any) string) {\n    if name == \"\" || extract == nil {\n        log.Printf(\"skipping context tag registration: name=%q extractNil=%v\", name, extract == nil)\n        return\n    }\n    logger.RegisterContextTag(name, extract)\n}","typeGuard":"func isValidTagRegistration(name string, extract func(any) string) bool {\n    return name != \"\" && extract != nil\n}","tryCatchPattern":null,"preventionTips":["Guard RegisterContextTag calls with non-empty-name and non-nil-extractor checks.","Register tags in init() from a static table you can audit, rather than dynamic loops.","Unit-test init-time registration so empty/nil entries fail CI, not runtime."],"tags":["logger","tag-registry","config","startup-panic"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}