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 blockView on GitHub (pinned to a84bbb65e3)
Solutions
- Reduce the data stored in the block's fields map (trim text content, move large blobs to attachments or separate blocks)
- Split an oversized block (e.g. a huge table or text card) into multiple smaller blocks
- If you legitimately need larger blocks, raise BlockFieldsMaxRunes in server/model/block.go and any matching client-side limit, understanding the storage impact
- 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
- Measure the serialized size of fields before insert/update
- Split large content (tables, long text) into multiple blocks
- Avoid storing base64/binary data in block fields
- Keep a client-side constant mirroring BlockFieldsMaxRunes so limits stay in sync
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
- at least one board is required
- at least one block is required
- team ID cannot be empty
- board ids and patches need to match
- block ids and patches need to match
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/8636e52a9ff91f01.
Report an issue: GitHub.