mattermost-community/focalboard · error
cannot upsert notification hint: %w
Error message
cannot upsert notification hint: %w
What it means
notifySubscribers wraps an error from UpsertNotificationHint when persisting the notification hint (subscriber, block, modified-by) to the database fails. The hint mechanism throttles/deduplicates block-change notifications; without a successful upsert the subscriber will not be notified. The root cause (store error) is preserved with %w.
Source
Thrown at server/services/notify/notifysubscriptions/subscriptions_backend.go:173
}
return merr.ErrorOrNil()
}
// notifySubscribers triggers a change notification for subscribers by writing a notification hint to the database.
func (b *Backend) notifySubscribers(subs []*model.Subscriber, blockID string, idType model.BlockType, modifiedByID string) error {
if len(subs) == 0 {
return nil
}
hint := &model.NotificationHint{
BlockType: idType,
BlockID: blockID,
ModifiedByID: modifiedByID,
}
hint, err := b.appAPI.UpsertNotificationHint(hint, b.getBlockUpdateFreq(idType))
if err != nil {
return fmt.Errorf("cannot upsert notification hint: %w", err)
}
if err := b.notifier.onNotifyHint(hint); err != nil {
return err
}
return nil
}
// OnMention satisfies the `MentionListener` interface and is called whenever a @mention notification
// is sent. Here we create a subscription for the mentioned user to the card.
func (b *Backend) OnMention(userID string, evt notify.BlockChangeEvent) {
if evt.Card == nil {
b.logger.Debug("Cannot subscribe mentioned user to nil card",
mlog.String("user_id", userID),
mlog.String("block_id", evt.BlockChanged.ID),
)
return
}View on GitHub (pinned to a84bbb65e3)
Solutions
- Check the wrapped cause from UpsertNotificationHint (DB connectivity, constraint errors)
- Verify the notification hints table exists and matches the current schema
- Validate that the subscriber record still exists and is valid
- Retry the notification — hint writes are idempotent upserts
Example fix
// before
hint, err := b.appAPI.UpsertNotificationHint(hint, freq)
if err != nil {
return fmt.Errorf("cannot upsert notification hint: %w", err)
}
// after
hint, err := b.appAPI.UpsertNotificationHint(hint, freq)
if err != nil {
logger.Error("hint upsert failed", "blockID", blockID, "err", err)
return fmt.Errorf("cannot upsert notification hint: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
// verify subscriber exists before a change that will notify
if _, err := appAPI.GetSubscribersForBlock(blockID); err != nil {
return err
} Try / catch
err := backend.BlockChanged(evt)
if err != nil && strings.Contains(err.Error(), "cannot upsert notification hint") {
// transient DB issue; safe to retry the notification path
return retryBlockNotify(evt)
} Prevention
- Ensure the notification hints schema matches the running version after upgrades
- Monitor database connection pool saturation during heavy editing
- Keep hint upserts idempotent so retries are safe
- Alert on persistent UpsertNotificationHint failures — subscribers silently miss notifications
When it happens
Trigger: A block change occurs for a subscribed block and the appAPI.UpsertNotificationHint call fails — database unavailable, constraint violation on the hints table, invalid block/subscriber IDs, or the block update frequency config cannot be resolved (unknown block type).
Common situations: Database connection pool exhaustion under heavy editing; schema drift after upgrading Focalboard where the hints table is missing/outdated; orphaned subscriber records pointing at deleted users.
Related errors
- cannot notify block subscribers for block %s: %w
- mention not permitted
- invalid subscriber type
- card limit value is invalid
- database type is unsupported
AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30).
Data as JSON: /api/errors/82d80b2d2eb4763d.
Report an issue: GitHub.