{"record":{"id":"525841328f4714bb","repo":"mattermost-community/focalboard","slug":"insertboard-error-occurred-while-inserting-board","errorCode":null,"errorMessage":"insertBoard error occurred while inserting board %s: %w","messagePattern":"insertBoard error occurred while inserting board (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/sqlstore/board.go","lineNumber":390,"sourceCode":"\t\t\tSet(\"template_version\", board.TemplateVersion).\n\t\t\tSet(\"properties\", propertiesBytes).\n\t\t\tSet(\"card_properties\", cardPropertiesBytes).\n\t\t\tSet(\"update_at\", board.UpdateAt).\n\t\t\tSet(\"delete_at\", board.DeleteAt)\n\n\t\tif _, err := query.Exec(); err != nil {\n\t\t\ts.logger.Error(`InsertBoard error occurred while updating existing board`, mlog.String(\"boardID\", board.ID), mlog.Err(err))\n\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}","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/sqlstore/board.go#L372-L408","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nboard.ID = someFixedID // race-prone across replicas\n// after\nif board.ID == \"\" {\n    board.ID = utils.NewID() // unique per insert\n}\n_, err := insertBoard(board)","handlingStrategy":"validation","validationCode":"func boardInsertable(b *model.Board) error {\n    if b.ID == \"\" { return fmt.Errorf(\"board ID required\") }\n    if len(b.Title) > 255 { return fmt.Errorf(\"title too long\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"board, err := store.InsertBoard(board, userID)\nif err != nil && strings.Contains(err.Error(), \"error occurred while inserting board\") {\n    if strings.Contains(err.Error(), \"Duplicate\") {\n        board.ID = utils.NewID() // regenerate on rare duplicate-key race\n        board, err = store.InsertBoard(board, userID)\n    }\n}","preventionTips":["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"],"tags":["database","insert","schema"],"backgroundTag":"board-insert-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}