mattermost-community/focalboard · error
history not found for board: %w
Error message
history not found for board: %w
What it means
getBoardDescendantModifiedInfo treats a nil result from getBoardHistory as 'no history rows exist for this board' and returns 'history not found for board'. As written it wraps err, which is nil at that point, so the formatted message contains '%!w(<nil>)'; the semantic meaning is that the board has no history entries at all.
Source
Thrown at server/app/boards.go:113
}
boards, err := a.store.GetBoardHistory(boardID, opts)
if err != nil {
return nil, fmt.Errorf("could not get history for board: %w", err)
}
if len(boards) == 0 {
return nil, nil
}
return boards[0], nil
}
func (a *App) getBoardDescendantModifiedInfo(boardID string, latest bool) (int64, string, error) {
board, err := a.getBoardHistory(boardID, latest)
if err != nil {
return 0, "", err
}
if board == nil {
return 0, "", fmt.Errorf("history not found for board: %w", err)
}
var timestamp int64
modifiedBy := board.ModifiedBy
if latest {
timestamp = board.UpdateAt
} else {
timestamp = board.CreateAt
}
// use block_history to fetch blocks in case they were deleted and no longer exist in blocks table.
opts := model.QueryBlockHistoryOptions{
Limit: 1,
Descending: latest,
}
blocks, err := a.store.GetBlockHistoryDescendants(boardID, opts)
if err != nil {
return 0, "", fmt.Errorf("could not get blocks history descendants for board: %w", err)View on GitHub (pinned to a84bbb65e3)
Solutions
- Treat missing history as empty metadata on the caller side instead of an error, if acceptable for your use case.
- Create/update the board once through the app API so a history row is generated.
- Backfill history rows for legacy boards via a migration.
- Fix the source bug: return a dedicated sentinel (e.g. ErrHistoryNotFound) rather than wrapping nil err.
Example fix
// before
if board == nil {
return 0, "", fmt.Errorf("history not found for board: %w", err)
}
// after
if board == nil {
return 0, "", ErrBoardHistoryNotFound
} Defensive patterns
Strategy: fallback
Validate before calling
// detect the missing-history condition up front
_, err := app.GetBoard(boardID)
if err != nil {
return err
}
// no way to pre-check history rows via public API; fall back on error Try / catch
meta, err := app.GetBoardMetadata(boardID, latest)
if err != nil {
if strings.Contains(err.Error(), "history not found for board") {
meta = &model.BoardMetadata{} // fall back to empty metadata
} else {
return err
}
} Prevention
- Seed a history row whenever a board is created, including imports and manual inserts.
- Backfill history for boards created before history tracking existed.
- Treat 'no history' as empty metadata rather than a hard failure in consumers.
When it happens
Trigger: GetBoardMetadata (via getBoardDescendantModifiedInfo) on a board that has never had a history record inserted — e.g. boards created before history tracking existed, boards created directly in the DB, or newly created boards whose first history row has not been written.
Common situations: Legacy data predating the board-history feature; imports/migrations that skipped history; a bug where board creation does not seed a history entry.
Related errors
- cannot fetch board %s for DuplicateBlock: %w
- category is deleted
- could not get history for board: %w
- could not get blocks history descendants for board: %w
- %w userID: %s
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/2510ea30d5141ad2.
Report an issue: GitHub.