mattermost-community/focalboard · error
insertBoard error occurred while inserting board %s: %w
Error message
insertBoard error occurred while inserting board %s: %w
What it means
When no existing board shares the ID, insertBoard performs the INSERT into the boards table; a failed Exec raises this wrapped error. It is the plain-insert arm of the upsert logic and wraps the driver's error, so the root cause (unique constraint, connection, type mismatch) must be read from %w.
Source
Thrown at server/services/store/sqlstore/board.go:390
Set("template_version", board.TemplateVersion).
Set("properties", propertiesBytes).
Set("card_properties", cardPropertiesBytes).
Set("update_at", board.UpdateAt).
Set("delete_at", board.DeleteAt)
if _, err := query.Exec(); err != nil {
s.logger.Error(`InsertBoard error occurred while updating existing board`, mlog.String("boardID", board.ID), mlog.Err(err))
return nil, fmt.Errorf("insertBoard error occurred while updating existing board %s: %w", board.ID, err)
}
} else {
board.CreatedBy = userID
board.CreateAt = now
insertQueryValues["created_by"] = board.CreatedBy
insertQueryValues["create_at"] = board.CreateAt
query := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + "boards")
if _, err := query.Exec(); err != nil {
return nil, fmt.Errorf("insertBoard error occurred while inserting board %s: %w", board.ID, err)
}
}
// writing board history
query := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + "boards_history")
if _, err := query.Exec(); err != nil {
s.logger.Error("failed to insert board history", mlog.String("board_id", board.ID), mlog.Err(err))
return nil, fmt.Errorf("failed to insert board %s history: %w", board.ID, err)
}
return board, nil
}
func (s *SQLStore) patchBoard(db sq.BaseRunner, boardID string, boardPatch *model.BoardPatch, userID string) (*model.Board, error) {
existingBoard, err := s.getBoard(db, boardID)
if err != nil {
return nil, err
}View on GitHub (pinned to a84bbb65e3)
Solutions
- Read the wrapped driver error to distinguish constraint vs connection vs schema issues
- Run database migrations to ensure the boards schema matches your server version
- Add an idempotent retry with a NEW board ID if a duplicate-key race is suspected
- Verify field lengths/types conform to the schema (trim overly long titles/channel names)
Example fix
// before
board.ID = someFixedID // race-prone across replicas
// after
if board.ID == "" {
board.ID = utils.NewID() // unique per insert
}
_, err := insertBoard(board) Defensive patterns
Strategy: validation
Validate before calling
func boardInsertable(b *model.Board) error {
if b.ID == "" { return fmt.Errorf("board ID required") }
if len(b.Title) > 255 { return fmt.Errorf("title too long") }
return nil
} Try / catch
board, err := store.InsertBoard(board, userID)
if err != nil && strings.Contains(err.Error(), "error occurred while inserting board") {
if strings.Contains(err.Error(), "Duplicate") {
board.ID = utils.NewID() // regenerate on rare duplicate-key race
board, err = store.InsertBoard(board, userID)
}
} Prevention
- Always generate unique board IDs (utils.NewID()) rather than client-supplied ones
- Run schema migrations after every server upgrade
- Validate field lengths against schema limits before insert
- Avoid strict-mode-incompatible values (zero dates, wrong types) in board fields
When it happens
Trigger: InsertBoard/patchBoard/createBoardsAndBlocks/insertBoardWithAdmin inserting a new board where Exec fails — e.g. duplicate ID raced with another insert after the existence check, invalid column values, or DB connection failure.
Common situations: Two concurrent InsertBoard calls with the same generated ID (rare); schema drift (missing columns after upgrade without migration); values exceeding column sizes (e.g. very long titles/fields); MySQL strict mode rejecting zero dates.
Related errors
- invalid property schema
- card limit value is invalid
- database type is unsupported
- cannot create card: %w
- cannot notify block subscribers for block %s: %w
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/525841328f4714bb.
Report an issue: GitHub.