mattermost-community/focalboard · error

%w userID: %s

Error message

%w userID: %s

What it means

addBoardsToDefaultCategory assigns boards to the user's default 'Board' category in a team. If no default category can be found (no category named/type Board for that user+team), it wraps the package sentinel errNoDefaultCategoryFound with the userID. It is reached from CreateBoard, setBoardCategoryFromSource, AddMemberToBoard and CreateBoardsAndBlocks.

Source

Thrown at server/app/boards.go:293

	return newBoard, nil
}

func (a *App) addBoardsToDefaultCategory(userID, teamID string, boards []*model.Board) error {
	userCategoryBoards, err := a.GetUserCategoryBoards(userID, teamID)
	if err != nil {
		return err
	}

	defaultCategoryID := ""
	for _, categoryBoard := range userCategoryBoards {
		if categoryBoard.Name == defaultCategoryBoards {
			defaultCategoryID = categoryBoard.ID
			break
		}
	}

	if defaultCategoryID == "" {
		return fmt.Errorf("%w userID: %s", errNoDefaultCategoryFound, userID)
	}

	boardIDs := make([]string, len(boards))
	for i := range boards {
		boardIDs[i] = boards[i].ID
	}

	if err := a.AddUpdateUserCategoryBoard(teamID, userID, defaultCategoryID, boardIDs); err != nil {
		return err
	}

	return nil
}

func (a *App) PatchBoard(patch *model.BoardPatch, boardID, userID string) (*model.Board, error) {
	var oldChannelID string
	var isTemplate bool
	var oldMembers []*model.BoardMember

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Initialize the user's default categories for the team (call the category-initialization path, e.g. a.getOrCreateCategory / onboarding flow) before adding boards.
  2. Check errors.Is(err, errNoDefaultCategoryFound) to confirm the cause and handle it by creating the default 'Board' category.
  3. Verify the categories table has a row of type 'board' for (userID, teamID); create it if missing.
  4. When duplicating into another team, ensure category initialization runs for the target team first.

Example fix

// caller-side
err := a.CreateBoard(board, userID)
if err != nil && errors.Is(err, errNoDefaultCategoryFound) {
    if cErr := a.initializeDefaultCategories(userID, board.TeamID); cErr != nil {
        return cErr
    }
    return a.CreateBoard(board, userID) // retry after init
}
Defensive patterns

Strategy: validation

Validate before calling

categories, err := app.GetCategoriesForTeam(teamID, userID)
if err != nil {
    return err
}
hasDefault := false
for _, c := range categories {
    if c.Type == model.CategoryTypeBoard {
        hasDefault = true
        break
    }
}
if !hasDefault {
    if _, err := app.CreateCategory(&model.Category{Name: "Boards", TeamID: teamID, UserID: userID, Type: model.CategoryTypeBoard}, userID); err != nil {
        return err
    }
}

Type guard

func hasDefaultBoardCategory(cats []*model.Category) bool {
    for _, c := range cats {
        if c.Type == model.CategoryTypeBoard {
            return true
        }
    }
    return false
}

Try / catch

if err := a.CreateBoard(board, userID); err != nil {
    if errors.Is(err, errNoDefaultCategoryFound) {
        if cErr := a.initializeDefaultCategories(userID, board.TeamID); cErr != nil {
            return cErr
        }
        return a.CreateBoard(board, userID)
    }
    return err
}

Prevention

When it happens

Trigger: Creating a board or adding a member in a team where the user has no default board category: the team's categories were never initialized for that user, the default category was renamed/deleted, or category initialization failed at first login.

Common situations: Fresh teams where Onboarding/initializeCategories hasn't run; users whose categories were removed by a bug or manual DB edit; duplicated-board flows into a new team (toTeam) lacking the user's categories.

Related errors


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