{"record":{"id":"3d8523917744613a","repo":"mattermost-community/focalboard","slug":"board-ids-and-patches-need-to-match","errorCode":null,"errorMessage":"board ids and patches need to match","messagePattern":"board ids and patches need to match","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/model/boards_and_blocks.go","lineNumber":17,"sourceCode":"package model\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/mattermost/focalboard/server/utils\"\n\n\t\"github.com/mattermost/mattermost/server/public/shared/mlog\"\n)\n\nvar ErrNoBoardsInBoardsAndBlocks = errors.New(\"at least one board is required\")\nvar ErrNoBlocksInBoardsAndBlocks = errors.New(\"at least one block is required\")\nvar ErrNoTeamInBoardsAndBlocks = errors.New(\"team ID cannot be empty\")\nvar ErrBoardIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New(\"board ids and patches need to match\")\nvar ErrBlockIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New(\"block ids and patches need to match\")\n\ntype BlockDoesntBelongToAnyBoardErr struct {\n\tblockID string\n}\n\nfunc (e BlockDoesntBelongToAnyBoardErr) Error() string {\n\treturn fmt.Sprintf(\"block %s doesn't belong to any board\", e.blockID)\n}\n\n// BoardsAndBlocks is used to operate over boards and blocks at the\n// same time\n// swagger:model\ntype BoardsAndBlocks struct {\n\t// The boards\n\t// required: false\n\tBoards []*Board `json:\"boards\"`\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/model/boards_and_blocks.go#L1-L35","documentation":"ErrBoardIDsAndPatchesMissmatchInBoardsAndBlocks is returned by BoardsAndBlocks.IsValid() when using the patch variant of boards-and-blocks and the number (or order) of board IDs does not match the number of board patches supplied. Each patch must correspond to exactly one board ID.","triggerScenarios":"PATCH /api/v2/boards-and-blocks with BoardIDs and BoardPatches arrays of different lengths, or misaligned ordering.","commonSituations":"Off-by-one bugs in bulk update tooling; a board deleted between fetching IDs and building patches; client code appending an ID but not its patch (or vice versa).","solutions":["Ensure BoardIDs.length === BoardPatches.length before sending the request","Build the two arrays together in the same loop/map so they stay aligned","If a board was deleted mid-operation, re-fetch the board list and rebuild the patch set"],"exampleFix":"// before\npayload.boardIDs = boards.map(b => b.id)\npayload.boardPatches = boards.filter(b => b.toUpdate).map(b => patchOf(b))\n// after\nconst toUpdate = boards.filter(b => b.toUpdate)\npayload.boardIDs = toUpdate.map(b => b.id)\npayload.boardPatches = toUpdate.map(b => patchOf(b))","handlingStrategy":"validation","validationCode":"if (payload.boardIDs.length !== payload.boardPatches.length) {\n  throw new Error('board ids and patches must be the same length')\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.patchBoardsAndBlocks(payload)\n} catch (err) {\n  if (err.message?.includes('board ids and patches need to match')) {\n    console.error('Align boardIDs and boardPatches arrays 1:1')\n  } else throw err\n}","preventionTips":["Build IDs and patches from the same filtered collection in one pass","Never append to one array without the other","Re-fetch state if boards may have changed mid-operation"],"tags":["go","validation","patch","bad-request"],"backgroundTag":"array-length-mismatch","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}