{"id":"9433e456b1d96ecf","repo":"gofiber/fiber","slug":"log-context-tag-is-reserved","errorCode":null,"errorMessage":"log: context tag is reserved","messagePattern":"log: context tag is reserved","errorType":"validation","errorClass":"ErrContextTagReserved","httpStatus":null,"severity":"error","filePath":"log/context.go","lineNumber":87,"sourceCode":"// contextTemplate holds the precompiled format. Loads on the log hot path\n// happen lock-free; rebuilds (write side) hold contextMu.\nvar contextTemplate atomic.Pointer[logtemplate.Template[any, ContextData]]\n\nvar (\n\t// contextMu guards rebuilds of contextFormat / contextTags. Readers of\n\t// the compiled template (writeContext) use contextTemplate.Load directly.\n\tcontextMu     sync.RWMutex\n\tcontextFormat = DefaultFormat\n\tcontextTags   = defaultContextTagMap()\n)\n\nvar (\n\t// ErrContextTagInvalid is returned by RegisterContextTag and SetContextTemplate\n\t// when the supplied tag name or renderer is empty.\n\tErrContextTagInvalid = errors.New(\"log: context tag name and function are required\")\n\t// ErrContextTagReserved is returned by RegisterContextTag and SetContextTemplate\n\t// when the caller attempts to override the reserved TagContextValue (\"value:\") tag.\n\tErrContextTagReserved = errors.New(\"log: context tag is reserved\")\n)\n\n// SetContextTemplate configures contextual fields rendered by WithContext for Fiber's default logger.\n// Pass an empty ContextConfig (or ContextConfig{Format: DefaultFormat}) to disable contextual fields.\n// It returns an error if config.Format cannot be parsed or if config.CustomTags attempts to\n// override the reserved TagContextValue tag.\nfunc SetContextTemplate(config ContextConfig) error {\n\tif _, ok := config.CustomTags[TagContextValue]; ok {\n\t\treturn ErrContextTagReserved\n\t}\n\n\tcontextMu.Lock()\n\tdefer contextMu.Unlock()\n\n\t// Cloning the live tag map preserves prior RegisterContextTag entries —\n\t// callers that interleave RegisterContextTag with SetContextTemplate\n\t// expect the registration to remain visible. CustomTags layer on top.\n\ttags := maps.Clone(contextTags)","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/log/context.go#L69-L105","documentation":"ErrContextTagReserved ('log: context tag is reserved', log/context.go:87) is returned by log.RegisterContextTag (log/context.go:140) and SetContextTemplate (log/context.go:96) when the caller tries to register or override the reserved tag 'value:' (TagContextValue). That tag is the built-in renderer for ${value:KEY} context-value lookups and is re-installed by Fiber itself, so user overrides are rejected to preserve its semantics.","triggerScenarios":"Calling RegisterContextTag(\"value:\", fn), or passing CustomTags: map[string]ContextTagFunc{\"value:\": fn} to SetContextTemplate. Any attempt to claim the reserved name yields this error. Must variants panic with it.","commonSituations":"Wanting a generic 'value' tag and not realizing 'value:' is reserved, or programmatically registering tags from a list that happens to include 'value:'. Confusing the bare vs parametric forms.","solutions":["Choose a different, non-reserved tag name for your custom renderer (e.g. 'myvalue' or 'data:').","Filter 'value:' out of any auto-generated CustomTags map before calling SetContextTemplate.","To add context values, rely on the built-in ${value:KEY} tag instead of overriding it."],"exampleFix":"// before\nlog.SetContextTemplate(log.ContextConfig{\n    CustomTags: map[string]log.ContextTagFunc{\n        \"value:\": myRenderer, // reserved -> ErrContextTagReserved\n    },\n    Format: \"${value:userId}\",\n})\n\n// after\nlog.SetContextTemplate(log.ContextConfig{\n    CustomTags: map[string]log.ContextTagFunc{\n        \"myvalue:\": myRenderer, // custom parametric tag\n    },\n    Format: \"${myvalue:userId}\",\n})","handlingStrategy":"validation","validationCode":"// Strip the reserved tag from auto-generated CustomTags.\ndelete(customTags, log.TagContextValue) // \"value:\"\nif err := log.SetContextTemplate(log.ContextConfig{CustomTags: customTags, Format: fmtStr}); err != nil {\n    return err\n}","typeGuard":null,"tryCatchPattern":"if err := log.RegisterContextTag(tag, fn); err != nil {\n    if errors.Is(err, log.ErrContextTagReserved) {\n        log.Printf(\"tag %q is reserved; rename it\", tag)\n        return\n    }\n    return err\n}","preventionTips":["Never attempt to register the reserved 'value:' tag.","Filter reserved names out of generated CustomTags maps.","Reuse the built-in ${value:KEY} tag for context-value lookups instead of overriding it."],"tags":["logging","context","config","reserved","fiber"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}