mattermost-community/focalboard · error

SearchBoardsForUserInTeam error getting unionSQL: %w

Error message

SearchBoardsForUserInTeam error getting unionSQL: %w

What it means

The three-way UNION (openBoardsQ UNION memberBoardsSQL UNION channelMemberBoardsSQL) failed ToSql() in SearchBoardsForUserInTeam. The combined builder was invalid at render time, usually inherited from an invalid underlying builder.

Source

Thrown at server/services/store/mattermostauthlayer/mattermostauthlayer.go:872

	memberBoardsSQL, memberBoardsArgs, err := memberBoardsQ.ToSql()
	if err != nil {
		return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting memberBoardsSQL: %w", err)
	}

	channelMemberBoardsSQL, channelMemberBoardsArgs, err := channelMemberBoardsQ.ToSql()
	if err != nil {
		return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting channelMemberBoardsSQL: %w", err)
	}

	unionQ := openBoardsQ.
		Prefix("(").
		Suffix(") UNION ("+memberBoardsSQL, memberBoardsArgs...).
		Suffix(") UNION ("+channelMemberBoardsSQL+")", channelMemberBoardsArgs...)

	unionSQL, unionArgs, err := unionQ.ToSql()
	if err != nil {
		return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting unionSQL: %w", err)
	}

	// if we're using postgres or sqlite, we need to replace the
	// question mark placeholder with the numbered dollar one, now
	// that the full query is built
	if s.dbType == model.PostgresDBType || s.dbType == model.SqliteDBType {
		var rErr error
		unionSQL, rErr = sq.Dollar.ReplacePlaceholders(unionSQL)
		if rErr != nil {
			return nil, fmt.Errorf("SearchBoardsForUserInTeam unable to replace unionSQL placeholders: %w", rErr)
		}
	}

	rows, err := s.mmDB.Query(unionSQL, unionArgs...)
	if err != nil {
		s.logger.Error(`searchBoardsForUserInTeam ERROR`, mlog.Err(err))
		return nil, err
	}

View on GitHub (pinned to a84bbb65e3)

Solutions

  1. Resolve any earlier memberBoardsSQL/channelMemberBoardsSQL build errors first.
  2. Check that each Suffix string's '?' placeholders match the appended args.
  3. Test unionQ construction in isolation with canned builders.
  4. Confirm the pinned squirrel version renders nested Prefix/Suffix unions correctly.
Defensive patterns

Strategy: try-catch

Try / catch

boards, err := store.GetBoardsForUserAndTeam(userID, teamID, term)
if err != nil {
	if strings.Contains(err.Error(), "SearchBoardsForUserInTeam error getting unionSQL") {
		logger.Error("three-way union query build failed", "err", err)
		return nil, ErrInternalSearch
	}
	return nil, err
}

Prevention

When it happens

Trigger: unionQ.ToSql() fails after chaining Prefix/Suffix unions of the three builders — typically propagating an earlier builder error or mismatched placeholder/args in the Suffix strings.

Common situations: Cascading from errors 86/87 root causes; hand-written Suffix SQL edited incorrectly; squirrel behavior changes.

Related errors


AI-assisted analysis of mattermost-community/focalboard@a84bbb65e3 (2026-08-30). Data as JSON: /api/errors/c58b6da9331638c8. Report an issue: GitHub.