{"record":{"id":"d0472f59cd3afa15","repo":"mattermost-community/focalboard","slug":"error-validating-block-s-w","errorCode":null,"errorMessage":"error validating block %s: %w","messagePattern":"error validating block (.+?): %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/sqlstore/blocks.go","lineNumber":232,"sourceCode":"\t\t}\n\n\t\terr = json.Unmarshal([]byte(fieldsJSON), &block.Fields)\n\t\tif err != nil {\n\t\t\t// handle this error\n\t\t\ts.logger.Error(`ERROR blocksFromRows fields`, mlog.Err(err))\n\n\t\t\treturn nil, err\n\t\t}\n\n\t\tresults = append(results, &block)\n\t}\n\n\treturn results, nil\n}\n\nfunc (s *SQLStore) insertBlock(db sq.BaseRunner, block *model.Block, userID string) error {\n\tif err := block.IsValid(); err != nil {\n\t\treturn fmt.Errorf(\"error validating block %s: %w\", block.ID, err)\n\t}\n\n\tfieldsJSON, err := json.Marshal(block.Fields)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texistingBlock, err := s.getBlock(db, block.ID)\n\tif err != nil && !model.IsErrNotFound(err) {\n\t\treturn err\n\t}\n\n\tblock.UpdateAt = utils.GetMillis()\n\tblock.ModifiedBy = userID\n\n\tinsertQuery := s.getQueryBuilder(db).Insert(\"\").\n\t\tColumns(\n\t\t\t\"channel_id\",","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/sqlstore/blocks.go#L214-L250","documentation":"This is a wrapped validation failure raised by insertBlock when the incoming model.Block fails block.IsValid(). It means the block (card, board item, text, etc.) violates Focalboard's structural rules (e.g. empty ID, invalid type, bad parent/child fields). The original validation error is preserved via %w so callers can inspect it with errors.As/Is against the model's ErrInvalidBlock error chain.","triggerScenarios":"Calling InsertBlock or InsertBlocks (or the higher-level patchBlock/createBoardsAndBlocks flows) with a block whose ID is empty, whose Type is not a registered block type, whose boardID/parentID references are malformed, or otherwise failing model.Block.IsValid().","commonSituations":"Importing JSON block dumps with missing or empty 'id' fields; writing client code that constructs blocks with a Type typo; API automation sending blocks without required fields; restoring backups with legacy/corrupted block shapes.","solutions":["Log/inspect the wrapped inner error (errors.Unwrap or %v of the returned error) to see exactly which field IsValid rejected","Ensure block.ID is set to a valid generated ID (e.g. utils.NewID()) before inserting","Ensure block.Type is one of the supported model.BlockType values and other required fields (BoardID, ParentID, Title) are populated","If the data comes from an import, pre-validate every block with block.IsValid() before calling the store"],"exampleFix":"// before\nblock := &model.Block{Title: \"hello\"}\ns.InsertBlock(block, userID)\n// after\nblock := &model.Block{ID: utils.NewID(), Type: model.TypeCard, Title: \"hello\", BoardID: boardID, ParentID: parentID}\nif err := block.IsValid(); err != nil {\n    return err\n}\ns.InsertBlock(block, userID)","handlingStrategy":"validation","validationCode":"func validForInsert(b *model.Block) error {\n    if b == nil || b.ID == \"\" {\n        return fmt.Errorf(\"block ID required\")\n    }\n    return b.IsValid()\n}\n// call before: if err := validForInsert(block); err != nil { return err }","typeGuard":"func isInsertableBlock(b *model.Block) bool {\n    return b != nil && b.ID != \"\" && b.IsValid() == nil\n}","tryCatchPattern":"if err := store.InsertBlock(block, userID); err != nil {\n    var verr error\n    if errors.As(err, &verr) && strings.Contains(err.Error(), \"error validating block\") {\n        return fmt.Errorf(\"block %s invalid: %w\", block.ID, err)\n    }\n    return err\n}","preventionTips":["Always assign a fresh ID (utils.NewID()) to programmatically created blocks","Run block.IsValid() on imported/bulk data before calling the store","Keep block.Type within the supported set defined in the model package","Log the unwrapped inner error to pinpoint the rejected field"],"tags":["validation","data-model","database"],"backgroundTag":"block-validation-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}