mattermost-community/focalboard · error

block fields size limit exceeded

Error message

block fields size limit exceeded

What it means

ErrBlockFieldsSizeLimitExceeded is a sentinel validation error in the Focalboard server model layer. It is returned when a Block's fields JSON payload exceeds BlockFieldsMaxRunes (800,000 runes). It guards the database and API against oversized block payloads.

Source

Thrown at server/model/block.go:22

	"encoding/json"
	"errors"
	"io"
	"strconv"
	"unicode/utf8"

	"github.com/mattermost/focalboard/server/services/audit"
)

const (
	BlockTitleMaxBytes  = 65535                  // Maximum size of a TEXT column in MySQL
	BlockTitleMaxRunes  = BlockTitleMaxBytes / 4 // Assume a worst-case representation
	BlockFieldsMaxRunes = 800000
)

var (
	ErrBlockEmptyBoardID            = errors.New("boardID is empty")
	ErrBlockTitleSizeLimitExceeded  = errors.New("block title size limit exceeded")
	ErrBlockFieldsSizeLimitExceeded = errors.New("block fields size limit exceeded")
)

// Block is the basic data unit
// swagger:model
type Block struct {
	// The id for this block
	// required: true
	ID string `json:"id"`

	// The id for this block's parent block. Empty for root blocks
	// required: false
	ParentID string `json:"parentId"`

	// The id for user who created this block
	// required: true
	CreatedBy string `json:"createdBy"`

	// The id for user who last modified this block

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Reduce the data stored in the block's fields map (trim text content, move large blobs to attachments or separate blocks)
  2. Split an oversized block (e.g. a huge table or text card) into multiple smaller blocks
  3. If you legitimately need larger blocks, raise BlockFieldsMaxRunes in server/model/block.go and any matching client-side limit, understanding the storage impact
  4. Check the server response for IsErrBadRequest handling — the API returns this as a 400 bad request, so inspect which block in a batch failed

Example fix

// before
block.Fields = bigFieldsMap // >800k runes, IsValid() fails
// after
if uniseg.GraphemeClusterCount(string(fieldsJSON)) > model.BlockFieldsMaxRunes {
    bigFieldsMap = trimOrSplitFields(bigFieldsMap)
}
block.Fields = bigFieldsMap // now under limit
Defensive patterns

Strategy: validation

Validate before calling

function isBlockWithinSizeLimit(fields) {
  const runes = uniseg ? uniseg.GraphemeClusterCount(JSON.stringify(fields)) : JSON.stringify(fields).length
  return runes <= 800000
}

Try / catch

try {
  await client.insertBlock(block)
} catch (err) {
  if (err.response?.status === 400 && /fields size limit/.test(err.message)) {
    console.error('Block fields exceed 800k runes; split or trim the block', block.id)
  } else throw err
}

Prevention

When it happens

Trigger: Calling block IsValid() (and thus any API that inserts/updates a block, e.g. POST/PUT /api/v2/blocks or boards-and-blocks import) with a block whose 'fields' map serializes to more than 800000 runes.

Common situations: Clients importing large table/card contents, plugins or migrations writing huge custom field payloads, or copying blocks with embedded images/base64 data into the fields map.

Related errors


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