{"record":{"id":"e50bf4ca3b9ab91e","repo":"uber-go/zap","slug":"can-t-unmarshal-a-nil-level","errorCode":null,"errorMessage":"can't unmarshal a nil *Level","messagePattern":"can't unmarshal a nil \\*Level","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"zapcore/level.go","lineNumber":29,"sourceCode":"// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\npackage zapcore\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar errUnmarshalNilLevel = errors.New(\"can't unmarshal a nil *Level\")\n\n// A Level is a logging priority. Higher levels are more important.\ntype Level int8\n\nconst (\n\t// DebugLevel logs are typically voluminous, and are usually disabled in\n\t// production.\n\tDebugLevel Level = iota - 1\n\t// InfoLevel is the default logging priority.\n\tInfoLevel\n\t// WarnLevel logs are more important than Info, but don't need individual\n\t// human review.\n\tWarnLevel\n\t// ErrorLevel logs are high-priority. If an application is running smoothly,\n\t// it shouldn't generate any error-level logs.\n\tErrorLevel\n\t// DPanicLevel logs are particularly important errors. In development the\n\t// logger panics after writing the message.","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/uber-go/zap/blob/bbd4ecbd8760678fdbac94c93d9aca8069c83b2f/zapcore/level.go#L11-L47","documentation":"zapcore.Level.UnmarshalText on a nil *Level cannot store the parsed result anywhere, so it returns the sentinel errUnmarshalNilLevel. This guard exists because the pointer receiver would otherwise dereference nil.","triggerScenarios":"var l *zapcore.Level; l.UnmarshalText([]byte(\"info\")) — calling UnmarshalText (or UnmarshalJSON, which routes through it) through a nil pointer.","commonSituations":"Unmarshaling config structs where the Level field pointer is nil and code calls its method directly; reflection-based decoders invoking methods on nil pointer fields.","solutions":["Declare a value zapcore.Level and call l.UnmarshalText(...) on its address: (&l).UnmarshalText(...)","Ensure the enclosing struct's *Level field is non-nil before calling its Unmarshal methods"],"exampleFix":"// before\nvar l *zapcore.Level\nl.UnmarshalText([]byte(\"info\"))\n// after\nvar l zapcore.Level\nerr := l.UnmarshalText([]byte(\"info\"))","handlingStrategy":"type-guard","validationCode":"var lvl zapcore.Level\nif err := lvl.UnmarshalText([]byte(s)); err != nil {\n    return err\n}","typeGuard":"func unmarshalLevel(s string) (zapcore.Level, error) {\n    var l zapcore.Level\n    if err := l.UnmarshalText([]byte(s)); err != nil {\n        return 0, err\n    }\n    return l, nil\n}","tryCatchPattern":"var l zapcore.Level\nif err := l.UnmarshalText(data); err != nil {\n    return fmt.Errorf(\"parse level: %w\", err)\n}","preventionTips":["Never declare *Level just to call its Unmarshal methods; use a value","Check struct *Level fields for nil before invoking methods","When unmarshaling config, use zapcore.Level values or initialize pointers first"],"tags":["zapcore","level","unmarshal","go","nil-pointer"],"backgroundTag":"nil-pointer-unmarshal","analyzedSha":"bbd4ecbd8760678fdbac94c93d9aca8069c83b2f","analyzedAt":"2026-08-31T13:01:40.228Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}