mattermost-community/focalboard · error

board ids and patches need to match

Error message

board ids and patches need to match

What it means

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.

Source

Thrown at server/model/boards_and_blocks.go:17

package model

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"github.com/mattermost/focalboard/server/utils"

	"github.com/mattermost/mattermost/server/public/shared/mlog"
)

var ErrNoBoardsInBoardsAndBlocks = errors.New("at least one board is required")
var ErrNoBlocksInBoardsAndBlocks = errors.New("at least one block is required")
var ErrNoTeamInBoardsAndBlocks = errors.New("team ID cannot be empty")
var ErrBoardIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New("board ids and patches need to match")
var ErrBlockIDsAndPatchesMissmatchInBoardsAndBlocks = errors.New("block ids and patches need to match")

type BlockDoesntBelongToAnyBoardErr struct {
	blockID string
}

func (e BlockDoesntBelongToAnyBoardErr) Error() string {
	return fmt.Sprintf("block %s doesn't belong to any board", e.blockID)
}

// BoardsAndBlocks is used to operate over boards and blocks at the
// same time
// swagger:model
type BoardsAndBlocks struct {
	// The boards
	// required: false
	Boards []*Board `json:"boards"`

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Ensure BoardIDs.length === BoardPatches.length before sending the request
  2. Build the two arrays together in the same loop/map so they stay aligned
  3. If a board was deleted mid-operation, re-fetch the board list and rebuild the patch set

Example fix

// before
payload.boardIDs = boards.map(b => b.id)
payload.boardPatches = boards.filter(b => b.toUpdate).map(b => patchOf(b))
// after
const toUpdate = boards.filter(b => b.toUpdate)
payload.boardIDs = toUpdate.map(b => b.id)
payload.boardPatches = toUpdate.map(b => patchOf(b))
Defensive patterns

Strategy: validation

Validate before calling

if (payload.boardIDs.length !== payload.boardPatches.length) {
  throw new Error('board ids and patches must be the same length')
}

Try / catch

try {
  await client.patchBoardsAndBlocks(payload)
} catch (err) {
  if (err.message?.includes('board ids and patches need to match')) {
    console.error('Align boardIDs and boardPatches arrays 1:1')
  } else throw err
}

Prevention

When it happens

Trigger: PATCH /api/v2/boards-and-blocks with BoardIDs and BoardPatches arrays of different lengths, or misaligned ordering.

Common situations: 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).

Related errors


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