{"record":{"id":"e097787d38aabb0b","repo":"mattermost-community/focalboard","slug":"http-handler-panic","errorCode":null,"errorMessage":"http handler panic","messagePattern":"http handler panic","errorType":"http","errorClass":null,"httpStatus":500,"severity":"critical","filePath":"server/api/api.go","lineNumber":30,"sourceCode":"\t\"github.com/mattermost/focalboard/server/model\"\n\t\"github.com/mattermost/focalboard/server/services/audit\"\n\t\"github.com/mattermost/focalboard/server/services/permissions\"\n\n\t\"github.com/mattermost/mattermost/server/public/shared/mlog\"\n)\n\nconst (\n\tHeaderRequestedWith    = \"X-Requested-With\"\n\tHeaderRequestedWithXML = \"XMLHttpRequest\"\n\tUploadFormFileKey      = \"file\"\n\tTrue                   = \"true\"\n\n\tErrorNoTeamCode    = 1000\n\tErrorNoTeamMessage = \"No team\"\n)\n\nvar (\n\tErrHandlerPanic = errors.New(\"http handler panic\")\n)\n\n// ----------------------------------------------------------------------------------------------------\n// REST APIs\n\ntype API struct {\n\tapp             *app.App\n\tauthService     string\n\tpermissions     permissions.PermissionsService\n\tsingleUserToken string\n\tMattermostAuth  bool\n\tlogger          mlog.LoggerIFace\n\taudit           *audit.Audit\n}\n\nfunc NewAPI(\n\tapp *app.App,\n\tsingleUserToken string,","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/api/api.go#L12-L48","documentation":"ErrHandlerPanic is a sentinel error created in api.go and used by the HTTP middleware to convert a recovered panic from a handler goroutine into a 500-style JSON error response. It signals an unexpected crash inside an API handler, not a domain condition.","triggerScenarios":"Any API handler panics (nil pointer, index out of range, failed type assertion, nil store field) and the recover middleware writes the response using ErrHandlerPanic as the error value.","commonSituations":"Bugs in handlers after deploys; nil fields on API struct before Init completes; malformed request data causing unexpected nil dereferences in handler code.","solutions":["Check server logs for the recovered panic stack trace to find the real faulting handler","Fix the nil-dereference/type assertion bug in the specific handler","Add nil/argument guards in the handler and cover it with a test"],"exampleFix":"// before\nfunc (a *API) handleX(w http.ResponseWriter, r *http.Request) {\n    b := a.store.GetBoard(props[\"boardID\"]) // panics if missing\n}\n// after\nfunc (a *API) handleX(w http.ResponseWriter, r *http.Request) {\n    boardID := props[\"boardID\"]\n    if boardID == \"\" {\n        a.errorResponse(w, r, model.NewErrNotFound(\"boardID\"))\n        return\n    }\n    b := a.store.GetBoard(boardID)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if errors.Is(err, api.ErrHandlerPanic) {\n        logger.Error(\"handler panicked\", \"err\", err)\n        http.Error(w, \"internal server error\", http.StatusInternalServerError)\n        return\n    }\n}","preventionTips":["Recover-with-log middleware should always include the panic stack trace","Nil-check store/config fields in handlers before use","Write handler tests with malformed/missing inputs to catch panics pre-deploy","Avoid unchecked type assertions in handlers; use the comma-ok form"],"tags":["panic","http","middleware","recovery"],"backgroundTag":"http-handler-panic","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}