mattermost-community/focalboard · critical

http handler panic

Error message

http handler panic

What it means

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.

Source

Thrown at server/api/api.go:30

	"github.com/mattermost/focalboard/server/model"
	"github.com/mattermost/focalboard/server/services/audit"
	"github.com/mattermost/focalboard/server/services/permissions"

	"github.com/mattermost/mattermost/server/public/shared/mlog"
)

const (
	HeaderRequestedWith    = "X-Requested-With"
	HeaderRequestedWithXML = "XMLHttpRequest"
	UploadFormFileKey      = "file"
	True                   = "true"

	ErrorNoTeamCode    = 1000
	ErrorNoTeamMessage = "No team"
)

var (
	ErrHandlerPanic = errors.New("http handler panic")
)

// ----------------------------------------------------------------------------------------------------
// REST APIs

type API struct {
	app             *app.App
	authService     string
	permissions     permissions.PermissionsService
	singleUserToken string
	MattermostAuth  bool
	logger          mlog.LoggerIFace
	audit           *audit.Audit
}

func NewAPI(
	app *app.App,
	singleUserToken string,

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Check server logs for the recovered panic stack trace to find the real faulting handler
  2. Fix the nil-dereference/type assertion bug in the specific handler
  3. Add nil/argument guards in the handler and cover it with a test

Example fix

// before
func (a *API) handleX(w http.ResponseWriter, r *http.Request) {
    b := a.store.GetBoard(props["boardID"]) // panics if missing
}
// after
func (a *API) handleX(w http.ResponseWriter, r *http.Request) {
    boardID := props["boardID"]
    if boardID == "" {
        a.errorResponse(w, r, model.NewErrNotFound("boardID"))
        return
    }
    b := a.store.GetBoard(boardID)
}
Defensive patterns

Strategy: try-catch

Try / catch

if err != nil {
    if errors.Is(err, api.ErrHandlerPanic) {
        logger.Error("handler panicked", "err", err)
        http.Error(w, "internal server error", http.StatusInternalServerError)
        return
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: Bugs in handlers after deploys; nil fields on API struct before Init completes; malformed request data causing unexpected nil dereferences in handler code.

Related errors


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/e097787d38aabb0b. Report an issue: GitHub.