{"record":{"id":"56e79ff745e76ab7","repo":"mattermost-community/focalboard","slug":"moveboardstodefaultcategory-w","errorCode":null,"errorMessage":"moveBoardsToDefaultCategory: %w","messagePattern":"moveBoardsToDefaultCategory: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/app/category.go","lineNumber":178,"sourceCode":"\t\t\tsourceCategoryBoards = &categoryBoards[i]\n\t\t}\n\n\t\tif categoryBoards[i].Name == defaultCategoryBoards {\n\t\t\tdefaultCategoryID = categoryBoards[i].ID\n\t\t}\n\n\t\t// if both categories are found, no need to iterate furthur.\n\t\tif sourceCategoryBoards != nil && defaultCategoryID != \"\" {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif sourceCategoryBoards == nil {\n\t\treturn errCategoryNotFound\n\t}\n\n\tif defaultCategoryID == \"\" {\n\t\treturn fmt.Errorf(\"moveBoardsToDefaultCategory: %w\", errNoDefaultCategoryFound)\n\t}\n\n\tboardIDs := make([]string, len(sourceCategoryBoards.BoardMetadata))\n\tfor i := range sourceCategoryBoards.BoardMetadata {\n\t\tboardIDs[i] = sourceCategoryBoards.BoardMetadata[i].BoardID\n\t}\n\n\tif err := a.AddUpdateUserCategoryBoard(teamID, userID, defaultCategoryID, boardIDs); err != nil {\n\t\treturn fmt.Errorf(\"moveBoardsToDefaultCategory: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (a *App) ReorderCategories(userID, teamID string, newCategoryOrder []string) ([]string, error) {\n\tif err := a.verifyNewCategoriesMatchExisting(userID, teamID, newCategoryOrder); err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/app/category.go#L160-L196","documentation":"moveBoardsToDefaultCategory returns this error when the team has no default category to receive boards whose source category is being deleted. It wraps the sentinel errNoDefaultCategoryFound so callers can detect it with errors.Is. It surfaces through DeleteCategory whenever board reassignment is required but no default category exists for the user/team.","triggerScenarios":"Calling DeleteCategory (directly or via the REST DELETE category endpoint) on a category that contains boards, when the user's team has no default category — i.e., defaultCategoryID resolves to empty string — so the boards cannot be moved anywhere.","commonSituations":"Teams provisioned before default categories were introduced, or where the default category was deleted; test/seed data lacking a default category; API consumers deleting non-empty categories on freshly created teams.","solutions":["Ensure each team has a default category (create one if missing) before allowing category deletion","Check for the sentinel with errors.Is(err, errNoDefaultCategoryFound) and surface a clear message to create a default category first","Migrate legacy teams to have a default category","Delete or move the boards manually before deleting the category"],"exampleFix":"// before\nerr := app.DeleteCategory(userID, teamID, categoryID)\n// after\nerr := app.DeleteCategory(userID, teamID, categoryID)\nif errors.Is(err, errNoDefaultCategoryFound) {\n\t// create/recreate a default category for the team first\n}","handlingStrategy":"try-catch","validationCode":"cats, err := app.GetCategoriesForTeam(teamID, userID)\nif err != nil {\n\treturn err\n}\nhasDefault := false\nfor _, c := range cats {\n\tif c.ID == defaultCategoryID || (c.Type == model.CategoryTypeDefault) {\n\t\thasDefault = true\n\t}\n}\nif !hasDefault {\n\t// create a default category before deleting a non-empty one\n}","typeGuard":"func isNoDefaultCategory(err error) bool {\n\treturn errors.Is(err, errNoDefaultCategoryFound)\n}","tryCatchPattern":"err := app.DeleteCategory(userID, teamID, categoryID)\nif isNoDefaultCategory(err) {\n\t// prompt user to create a default category first\n}","preventionTips":["Never delete the team's default category","Provision a default category for every new team at creation time","Guard the delete UI: only allow deleting categories after boards are moved","Check for errNoDefaultCategoryFound sentinel with errors.Is"],"tags":["go","categories","boards","sentinel-error"],"backgroundTag":"missing-default-category","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}