mattermost-community/focalboard · error
category doesn't belong to user
Error message
category doesn't belong to user
What it means
ErrCategoryPermissionDenied indicates the category being modified does not belong to the requesting user. Categories (sidebar groupings of boards) are per-user, so update/delete operations verify ownership and return this sentinel error on mismatch. IsErrForbidden maps it to HTTP 403.
Source
Thrown at server/model/error.go:21
import (
"database/sql"
"errors"
"fmt"
"net/http"
"strings"
mmModel "github.com/mattermost/mattermost/server/public/model"
pluginapi "github.com/mattermost/mattermost/server/public/pluginapi"
)
var (
ErrViewsLimitReached = errors.New("views limit reached for board")
ErrPatchUpdatesLimitedCards = errors.New("patch updates cards that are limited")
ErrInsufficientLicense = errors.New("appropriate license required")
ErrCategoryPermissionDenied = errors.New("category doesn't belong to user")
ErrCategoryDeleted = errors.New("category is deleted")
ErrBoardMemberIsLastAdmin = errors.New("cannot leave a board with no admins")
ErrRequestEntityTooLarge = errors.New("request entity too large")
ErrInvalidBoardSearchField = errors.New("invalid board search field")
)
// ErrNotFound is an error type that can be returned by store APIs
// when a query unexpectedly fetches no records.
type ErrNotFound struct {
entity string
}
// NewErrNotFound creates a new ErrNotFound instance.
func NewErrNotFound(entity string) *ErrNotFound {
return &ErrNotFound{View on GitHub (pinned to a84bbb65e3)
Solutions
- Confirm the authenticated user owns the category before updating/deleting
- Create the category as the same user that will modify it
- Check you are not mixing up categoryID with boardID or another ID
Example fix
// before
err := app.UpdateCategory(userID, otherUsersCategoryID, patch)
// after
cat, err := app.GetCategory(userID, categoryID)
if err != nil || cat.UserID != userID {
return errors.New("category does not belong to user")
}
err = app.UpdateCategory(userID, categoryID, patch) Defensive patterns
Strategy: type-guard
Validate before calling
cat, err := app.GetCategory(userID, categoryID)
if err != nil || cat.UserID != userID {
// abort: not this user's category
} Type guard
func isCategoryPermissionErr(err error) bool {
return errors.Is(err, model.ErrCategoryPermissionDenied)
} Try / catch
err := app.DeleteCategory(userID, categoryID)
if errors.Is(err, model.ErrCategoryPermissionDenied) {
// show permission-denied message, do not retry
} Prevention
- Always verify category ownership before mutation
- Never reuse category IDs across user sessions
- Map this error to HTTP 403 in API handlers
When it happens
Trigger: UpdateCategory or DeleteCategory with a categoryID owned by a different user; passing another user's category ID due to stale client state or ID confusion.
Common situations: Admins trying to reorder another user's sidebar categories via API; clients caching category IDs across accounts; tests reusing fixtures from another user.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- category is deleted
- cannot leave a board with no admins
- mention not permitted
- moveBoardsToDefaultCategory: %w
- block fields size limit exceeded
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/f2f9f6b183397ecc.
Report an issue: GitHub.