mattermost-community/focalboard · error
cannot parse datetime '%s' for board_members_history scan: %
Error message
cannot parse datetime '%s' for board_members_history scan: %w
What it means
boardMemberHistoryEntriesFromRows parses the insert_at column of board_members_history rows into time.Time using a dialect-specific layout; when time.Parse fails on the string value, this error wraps the unparseable value and the underlying error. It means the database returned insert_at in an unexpected textual format.
Source
Thrown at server/services/store/sqlstore/board.go:183
err := rows.Scan(
&boardMemberHistoryEntry.BoardID,
&boardMemberHistoryEntry.UserID,
&boardMemberHistoryEntry.Action,
&insertAt,
)
if err != nil {
return nil, err
}
// parse the insert_at timestamp which is different based on database type.
dateTemplate := "2006-01-02T15:04:05Z0700"
if s.dbType == model.MysqlDBType {
dateTemplate = "2006-01-02 15:04:05.000000"
}
ts, err := time.Parse(dateTemplate, insertAt.String)
if err != nil {
return nil, fmt.Errorf("cannot parse datetime '%s' for board_members_history scan: %w", insertAt.String, err)
}
boardMemberHistoryEntry.InsertAt = ts
boardMemberHistoryEntries = append(boardMemberHistoryEntries, &boardMemberHistoryEntry)
}
return boardMemberHistoryEntries, nil
}
func (s *SQLStore) getBoardByCondition(db sq.BaseRunner, conditions ...interface{}) (*model.Board, error) {
boards, err := s.getBoardsByCondition(db, conditions...)
if err != nil {
return nil, err
}
return boards[0], nil
}
View on GitHub (pinned to a84bbb65e3)
Solutions
- Check the quoted datetime in the error to see the actual format returned and compare with the expected template
- Verify the MySQL driver version (e.g. go-sql-driver/mysql) returns DATETIME as '2006-01-02 15:04:05.000000'; add parseTime/loc DSN params if needed
- Ensure rows were written by Focalboard itself (not imported with foreign timestamp formats)
- If the driver can't be changed, patch the dateTemplate to match your DB's output format
Example fix
// before
dateTemplate := "2006-01-02T15:04:05Z0700"
if s.dbType == model.MysqlDBType {
dateTemplate = "2006-01-02 15:04:05.000000"
}
// after
dateTemplate := "2006-01-02T15:04:05Z0700"
if s.dbType == model.MysqlDBType {
dateTemplate = "2006-01-02 15:04:05.999999" // tolerate rows without fractional seconds
}
Defensive patterns
Strategy: validation
Validate before calling
func isExpectedDatetimeFormat(s string, dbType string) bool {
layout := "2006-01-02T15:04:05Z0700"
if dbType == "mysql" {
layout = "2006-01-02 15:04:05.000000"
}
_, err := time.Parse(layout, s)
return err == nil
} Try / catch
entries, err := store.GetBoardMemberHistory(boardID)
if err != nil && strings.Contains(err.Error(), "cannot parse datetime") {
log.Printf("unexpected insert_at format from DB: %v", err)
return fmt.Errorf("driver/DB timestamp format mismatch: %w", err)
} Prevention
- Use the supported MySQL driver with parseTime configured as the server expects
- Avoid external tools writing board_members_history rows with foreign timestamp formats
- Keep DB datetime column types/precision unchanged across migrations
- If your driver formats differently, align the dateTemplate with actual output
When it happens
Trigger: getBoardMemberHistory scanning rows where insert_at's string doesn't match '2006-01-02 15:04:05.000000' (MySQL) or '2006-01-02T15:04:05Z0700' (Postgres/SQLite) — e.g. a driver returning a different formatting or zero-time representation.
Common situations: MySQL servers/drivers configured with different datetime precision or strict formatting; using an alternate driver that formats DATETIME differently; reading history rows written by another tool/version with a different timestamp format; locale/timezone formatting leaks from custom DB settings.
Related errors
- invalid date property
- card limit value is invalid
- database type is unsupported
- cannot notify block subscribers for block %s: %w
- cannot upsert notification hint: %w
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/e5bebe298275a3ab.
Report an issue: GitHub.