{"record":{"id":"28619de79df0613f","repo":"mattermost-community/focalboard","slug":"block-ids-and-patches-need-to-match","errorCode":null,"errorMessage":"block ids and patches need to match","messagePattern":"block ids and patches need to match","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/model/boards_and_blocks.go","lineNumber":18,"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\n\t// The blocks","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/model/boards_and_blocks.go#L1-L36","documentation":"ErrBlockIDsAndPatchesMissmatchInBoardsAndBlocks is returned by BoardsAndBlocks.IsValid() when the patch variant's BlockIDs and BlockPatches arrays do not correspond one-to-one. Every block patch must have exactly one matching block ID.","triggerScenarios":"PATCH /api/v2/boards-and-blocks with BlockIDs and BlockPatches arrays of differing lengths or misaligned order.","commonSituations":"Bulk block update scripts with divergent filtering between IDs and patches; concurrent modifications where a block vanished between ID collection and patch construction.","solutions":["Ensure BlockIDs.length === BlockPatches.length before sending","Derive both arrays from the same filtered collection in a single pass","Re-fetch blocks and rebuild the patch payload if the board changed during the operation"],"exampleFix":"// before\npayload.blockIDs = blocks.map(b => b.id)\npayload.blockPatches = patches // possibly different length\n// after\nif (patches.length !== payload.blockIDs.length) {\n  throw new Error('block ids and patches must align')\n}\npayload.blockPatches = patches","handlingStrategy":"validation","validationCode":"if (payload.blockIDs.length !== payload.blockPatches.length) {\n  throw new Error('block 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('block ids and patches need to match')) {\n    console.error('Align blockIDs and blockPatches arrays 1:1')\n  } else throw err\n}","preventionTips":["Derive IDs and patches in the same loop from one source list","Validate array lengths before sending","Rebuild the payload after any concurrent modification"],"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"}