{"record":{"id":"3de8e6527a18e051","repo":"mattermost-community/focalboard","slug":"could-not-patch-file-ids-while-duplicating-board","errorCode":null,"errorMessage":"could not patch file IDs while duplicating board %s: %w","messagePattern":"could not patch file IDs while duplicating board (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/app/boards.go","lineNumber":194,"sourceCode":"\t// now that we have source board's category,\n\t// we send destination board to the same category\n\treturn a.AddUpdateUserCategoryBoard(teamID, userID, destinationCategoryID, []string{destinationBoardID})\n}\n\nfunc (a *App) DuplicateBoard(boardID, userID, toTeam string, asTemplate bool) (*model.BoardsAndBlocks, []*model.BoardMember, error) {\n\tbab, members, err := a.store.DuplicateBoard(boardID, userID, toTeam, asTemplate)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// copy any file attachments from the duplicated blocks.\n\terr = a.CopyAndUpdateCardFiles(boardID, userID, bab.Blocks, asTemplate)\n\tif err != nil {\n\t\tdbab := model.NewDeleteBoardsAndBlocksFromBabs(bab)\n\t\tif dErr := a.store.DeleteBoardsAndBlocks(dbab, userID); dErr != nil {\n\t\t\ta.logger.Error(\"Cannot delete board after duplication error when updating block's file info\", mlog.String(\"boardID\", bab.Boards[0].ID), mlog.Err(dErr))\n\t\t}\n\t\treturn nil, nil, fmt.Errorf(\"could not patch file IDs while duplicating board %s: %w\", boardID, err)\n\t}\n\n\tif !asTemplate {\n\t\tfor _, board := range bab.Boards {\n\t\t\tif categoryErr := a.setBoardCategoryFromSource(boardID, board.ID, userID, toTeam, asTemplate); categoryErr != nil {\n\t\t\t\treturn nil, nil, categoryErr\n\t\t\t}\n\t\t}\n\t}\n\n\ta.blockChangeNotifier.Enqueue(func() error {\n\t\tteamID := \"\"\n\t\tfor _, board := range bab.Boards {\n\t\t\tteamID = board.TeamID\n\t\t\ta.wsAdapter.BroadcastBoardChange(teamID, board)\n\t\t}\n\t\tfor _, block := range bab.Blocks {\n\t\t\tblk := block","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/app/boards.go#L176-L212","documentation":"DuplicateBoard duplicates a board (optionally as a template) into another team. After copying blocks it calls CopyAndUpdateCardFiles to patch file IDs on duplicated cards; if that fails, this error wraps the cause and the just-created duplicate board/blocks are deleted as rollback. The message includes the original boardID for correlation.","triggerScenarios":"App.DuplicateBoard (also invoked by createWelcomeBoard) where CopyAndUpdateCardFiles fails: file storage (S3/minio/local) unreachable, source card files missing, or the files-table update errors — right after the duplicate board blocks were inserted.","commonSituations":"Misconfigured FileSettings (bad S3 credentials/endpoint); orphaned file records pointing to deleted objects; network partition between app server and file store; disk full on local driver.","solutions":["Check the wrapped cause — most often file-store connectivity or credentials; fix FileSettings and retry the duplication.","Verify the source board's card files exist in the file store before duplicating.","Look for the preceding log line 'Cannot delete board after duplication error...' to clean up any leftover duplicate board if rollback also failed.","Ensure the storage backend has free space / network access, then repeat DuplicateBoard."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-flight file store check before duplicating\nfor _, f := range boardCardFileIDs {\n    if _, err := fileStore.Reader(f); err != nil {\n        return fmt.Errorf(\"file %s unreadable; fix storage before duplicating board\", f)\n    }\n}","typeGuard":null,"tryCatchPattern":"newBoard, _, err := app.DuplicateBoard(board, toTeam, userID, asTemplate)\nif err != nil {\n    if strings.Contains(err.Error(), \"could not patch file IDs\") {\n        // duplicate board was rolled back; check file-store config and retry\n        return retryAfterStorageCheck(board.ID, userID)\n    }\n    return err\n}","preventionTips":["Validate FileSettings (S3 credentials, endpoint, local driver disk space) before bulk duplication.","Verify source card files are readable before CopyAndUpdateCardFiles runs.","After a failure, check logs for the rollback message to ensure no duplicate board leaked.","Monitor file-store connectivity in health checks."],"tags":["board-duplication","files","storage","rollback"],"backgroundTag":"file-storage-unavailable","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}