{"record":{"id":"a8720ec4a11328d5","repo":"uber-go/zap","slug":"must-specify-logging-level","errorCode":null,"errorMessage":"must specify logging level","messagePattern":"must specify logging level","errorType":"http","errorClass":null,"httpStatus":400,"severity":"warning","filePath":"http_handler.go","lineNumber":123,"sourceCode":"\t\tw.WriteHeader(http.StatusMethodNotAllowed)\n\t\treturn enc.Encode(errorResponse{\n\t\t\tError: \"Only GET and PUT are supported.\",\n\t\t})\n\t}\n}\n\n// Decodes incoming PUT requests and returns the requested logging level.\nfunc decodePutRequest(contentType string, r *http.Request) (zapcore.Level, error) {\n\tif contentType == \"application/x-www-form-urlencoded\" {\n\t\treturn decodePutURL(r)\n\t}\n\treturn decodePutJSON(r.Body)\n}\n\nfunc decodePutURL(r *http.Request) (zapcore.Level, error) {\n\tlvl := r.FormValue(\"level\")\n\tif lvl == \"\" {\n\t\treturn 0, errors.New(\"must specify logging level\")\n\t}\n\tvar l zapcore.Level\n\tif err := l.UnmarshalText([]byte(lvl)); err != nil {\n\t\treturn 0, err\n\t}\n\treturn l, nil\n}\n\nfunc decodePutJSON(body io.Reader) (zapcore.Level, error) {\n\tvar pld struct {\n\t\tLevel *zapcore.Level `json:\"level\"`\n\t}\n\tif err := json.NewDecoder(body).Decode(&pld); err != nil {\n\t\treturn 0, fmt.Errorf(\"malformed request body: %v\", err)\n\t}\n\tif pld.Level == nil {\n\t\treturn 0, errors.New(\"must specify logging level\")\n\t}","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/uber-go/zap/blob/bbd4ecbd8760678fdbac94c93d9aca8069c83b2f/http_handler.go#L105-L141","documentation":"The HTTP log-level handler's PUT /log/level endpoint (URL form mode) requires a `level` form/query value. decodePutURL returns errors.New(\"must specify logging level\") when the `level` parameter is absent or empty before attempting UnmarshalText.","triggerScenarios":"Sending an HTTP PUT to the log-level handler endpoint without a `level` form value or query parameter, e.g. PUT /log/level with no body/params.","commonSituations":"Scripting level changes via curl and forgetting ?level=warn; proxies stripping query parameters; empty form posts.","solutions":["Include the level in the request, e.g. curl -X PUT 'http://host:port/log/level?level=debug' or send form value level=debug","Use a valid zapcore.Level text value (debug, info, warn, error, dpanic, panic, fatal)"],"exampleFix":"// before\ncurl -X PUT http://localhost:8080/log/level\n// after\ncurl -X PUT 'http://localhost:8080/log/level?level=warn'","handlingStrategy":"validation","validationCode":"// client side\nif lvl == \"\" {\n    return errors.New(\"level query/form parameter is required\")\n}\nreq, _ := http.NewRequest(http.MethodPut, fmt.Sprintf(\"http://host/log/level?level=%s\", url.QueryEscape(lvl)), nil)","typeGuard":null,"tryCatchPattern":"resp, err := client.Do(req)\nif err != nil || resp.StatusCode != http.StatusOK {\n    body, _ := io.ReadAll(resp.Body)\n    return fmt.Errorf(\"set level failed: %s\", body)\n}","preventionTips":["Always include ?level=<value> on PUT /log/level requests","Use valid zapcore.Level text values","Wrap endpoint calls in a helper that enforces the parameter"],"tags":["http","zap","go","request-validation"],"backgroundTag":"missing-request-parameter","analyzedSha":"bbd4ecbd8760678fdbac94c93d9aca8069c83b2f","analyzedAt":"2026-08-31T13:01:40.228Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}