{"record":{"id":"4e3b7e98283e02fd","repo":"mattermost-community/focalboard","slug":"failed-to-insert-board-s-history-w","errorCode":null,"errorMessage":"failed to insert board %s history: %w","messagePattern":"failed to insert board (.+?) history: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/sqlstore/board.go","lineNumber":398,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"insertBoard error occurred while updating existing board %s: %w\", board.ID, err)\n\t\t}\n\t} else {\n\t\tboard.CreatedBy = userID\n\t\tboard.CreateAt = now\n\t\tinsertQueryValues[\"created_by\"] = board.CreatedBy\n\t\tinsertQueryValues[\"create_at\"] = board.CreateAt\n\n\t\tquery := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + \"boards\")\n\t\tif _, err := query.Exec(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"insertBoard error occurred while inserting board %s: %w\", board.ID, err)\n\t\t}\n\t}\n\n\t// writing board history\n\tquery := insertQuery.SetMap(insertQueryValues).Into(s.tablePrefix + \"boards_history\")\n\tif _, err := query.Exec(); err != nil {\n\t\ts.logger.Error(\"failed to insert board history\", mlog.String(\"board_id\", board.ID), mlog.Err(err))\n\t\treturn nil, fmt.Errorf(\"failed to insert board %s history: %w\", board.ID, err)\n\t}\n\n\treturn board, nil\n}\n\nfunc (s *SQLStore) patchBoard(db sq.BaseRunner, boardID string, boardPatch *model.BoardPatch, userID string) (*model.Board, error) {\n\texistingBoard, err := s.getBoard(db, boardID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tboard := boardPatch.Patch(existingBoard)\n\treturn s.insertBoard(db, board, userID)\n}\n\nfunc (s *SQLStore) deleteBoard(db sq.BaseRunner, boardID, userID string) error {\n\treturn s.deleteBoardAndChildren(db, boardID, userID, false)\n}","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/sqlstore/board.go#L380-L416","documentation":"After successfully writing the boards row (insert or update), insertBoard writes an audit record into boards_history; if that INSERT Exec fails, this wrapped error is returned — the board itself may be persisted but the call reports failure. The board ID and driver error are logged server-side before wrapping.","triggerScenarios":"Any successful board write followed by a failing boards_history insert — typically because the boards_history table is missing (incomplete migration), corrupted, or the DB connection dropped between the two statements.","commonSituations":"Upgrading from versions without history tables without running full migrations; manually pruning boards_history and dropping required constraints/columns; disk-full or read-only replicas; transient connection loss mid-transaction.","solutions":["Read the wrapped err and server log 'failed to insert board history' for the driver detail","Run migrations to ensure the boards_history table exists and matches schema expectations","Check DB health: disk space, connection stability, read/write permissions on boards_history","Retry the operation — the main board row insert is the same operation, so a clean retry (with a new ID if duplicate-key arises) usually succeeds"],"exampleFix":"// before\n// boards_history table missing after partial migration\n// after: apply all migrations\nmigrate_db.sh  # creates boards_history\nrestart server","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"board, err := store.InsertBoard(board, userID)\nif err != nil && strings.Contains(err.Error(), \"failed to insert board\") {\n    // board may exist; check before retrying to avoid duplicate\n    if existing, gerr := store.GetBoard(board.ID); gerr != nil || existing == nil {\n        board, err = store.InsertBoard(board, userID)\n    }\n}","preventionTips":["Always run full migrations so boards_history exists and matches schema","Never manually drop/alter boards_history constraints or columns","Monitor disk space and replica health; history writes fail on read-only or full DBs","Treat insert failures as partial writes: verify board existence before blind retries"],"tags":["database","history","audit","migration"],"backgroundTag":"board-history-insert-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}