{"record":{"id":"5808539d4d05c0da","repo":"googleapis/mcp-toolbox","slug":"invalid-slog-level","errorCode":null,"errorMessage":"invalid slog level","messagePattern":"invalid slog level","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/log/log.go","lineNumber":126,"sourceCode":"\t\treturn slog.LevelError, nil\n\tdefault:\n\t\treturn slog.Level(-5), fmt.Errorf(\"invalid log level\")\n\t}\n}\n\n// Returns severity string based on level.\nfunc levelToSeverity(s string) (string, error) {\n\tswitch s {\n\tcase slog.LevelDebug.String():\n\t\treturn Debug, nil\n\tcase slog.LevelInfo.String():\n\t\treturn Info, nil\n\tcase slog.LevelWarn.String():\n\t\treturn Warn, nil\n\tcase slog.LevelError.String():\n\t\treturn Error, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"invalid slog level\")\n\t}\n}\n\ntype StructuredLogger struct {\n\toutLogger *slog.Logger\n\terrLogger *slog.Logger\n}\n\n// NewStructuredLogger create a Logger that logs messages using JSON.\nfunc NewStructuredLogger(outW, errW io.Writer, logLevel string) (Logger, error) {\n\t//Set log level\n\tvar programLevel = new(slog.LevelVar)\n\tslogLevel, err := SeverityToLevel(logLevel)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tprogramLevel.Set(slogLevel)\n","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/log/log.go#L108-L144","documentation":"levelToSeverity is the inverse mapping of SeverityToLevel: it converts a slog.Level string (\"DEBUG\",\"INFO\",\"WARN\",\"ERROR\") back into the library's Severity constant. It throws this error when the given slog level string is unrecognized, so severity cannot be rendered for output.","triggerScenarios":"Calling levelToSeverity (via the structured logger's formatting path) with a slog level whose String() is not one of DEBUG/INFO/WARN/ERROR — e.g. custom slog levels like slog.Level(-5).String(), or a raw string like \"warning\".","commonSituations":"Application code registers a custom slog.Level (e.g. slog.LevelDebug-4 for tracing) and the structured logger tries to render it; tests pass an arbitrary level string; the level was constructed numerically rather than from constants.","solutions":["Only use slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, or slog.LevelError with this logger.","Clamp or map custom slog levels to the nearest supported level before logging.","Handle the returned error in the formatting path by falling back to a default severity (e.g. INFO) instead of dropping the record."],"exampleFix":"// before\nlvl := slog.Level(-5) // custom trace level\nsev, err := log.LevelToSeverity(lvl.String())\n// after\nlvl := slog.LevelInfo\nsev, err := log.LevelToSeverity(lvl.String())","handlingStrategy":"fallback","validationCode":"func supportedSlogLevel(l slog.Level) bool {\n\tswitch l {\n\tcase slog.LevelDebug, slog.LevelInfo, slog.LevelWarn, slog.LevelError:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":"func isStandardLevelString(s string) bool {\n\treturn s == slog.LevelDebug.String() || s == slog.LevelInfo.String() ||\n\t\ts == slog.LevelWarn.String() || s == slog.LevelError.String()\n}","tryCatchPattern":"sev, err := log.LevelToSeverity(lvl.String())\nif err != nil {\n\tsev = \"INFO\" // fallback for custom/unknown slog levels\n}","preventionTips":["Only create loggers with the four standard slog levels.","Clamp custom levels (e.g. level-4 verbosity) into the nearest standard level before rendering.","Cover the severity-mapping path in unit tests with all levels your app can produce."],"tags":["logging","go","slog"],"backgroundTag":"invalid-log-level","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}