{"record":{"id":"c58b6da9331638c8","repo":"mattermost-community/focalboard","slug":"searchboardsforuserinteam-error-getting-unionsql","errorCode":null,"errorMessage":"SearchBoardsForUserInTeam error getting unionSQL: %w","messagePattern":"SearchBoardsForUserInTeam error getting unionSQL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/mattermostauthlayer/mattermostauthlayer.go","lineNumber":872,"sourceCode":"\n\tmemberBoardsSQL, memberBoardsArgs, err := memberBoardsQ.ToSql()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SearchBoardsForUserInTeam error getting memberBoardsSQL: %w\", err)\n\t}\n\n\tchannelMemberBoardsSQL, channelMemberBoardsArgs, err := channelMemberBoardsQ.ToSql()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SearchBoardsForUserInTeam error getting channelMemberBoardsSQL: %w\", err)\n\t}\n\n\tunionQ := openBoardsQ.\n\t\tPrefix(\"(\").\n\t\tSuffix(\") UNION (\"+memberBoardsSQL, memberBoardsArgs...).\n\t\tSuffix(\") UNION (\"+channelMemberBoardsSQL+\")\", channelMemberBoardsArgs...)\n\n\tunionSQL, unionArgs, err := unionQ.ToSql()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SearchBoardsForUserInTeam error getting unionSQL: %w\", err)\n\t}\n\n\t// if we're using postgres or sqlite, we need to replace the\n\t// question mark placeholder with the numbered dollar one, now\n\t// that the full query is built\n\tif s.dbType == model.PostgresDBType || s.dbType == model.SqliteDBType {\n\t\tvar rErr error\n\t\tunionSQL, rErr = sq.Dollar.ReplacePlaceholders(unionSQL)\n\t\tif rErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"SearchBoardsForUserInTeam unable to replace unionSQL placeholders: %w\", rErr)\n\t\t}\n\t}\n\n\trows, err := s.mmDB.Query(unionSQL, unionArgs...)\n\tif err != nil {\n\t\ts.logger.Error(`searchBoardsForUserInTeam ERROR`, mlog.Err(err))\n\t\treturn nil, err\n\t}","sourceCodeStart":854,"sourceCodeEnd":890,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/mattermostauthlayer/mattermostauthlayer.go#L854-L890","documentation":"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.","triggerScenarios":"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.","commonSituations":"Cascading from errors 86/87 root causes; hand-written Suffix SQL edited incorrectly; squirrel behavior changes.","solutions":["Resolve any earlier memberBoardsSQL/channelMemberBoardsSQL build errors first.","Check that each Suffix string's '?' placeholders match the appended args.","Test unionQ construction in isolation with canned builders.","Confirm the pinned squirrel version renders nested Prefix/Suffix unions correctly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"boards, err := store.GetBoardsForUserAndTeam(userID, teamID, term)\nif err != nil {\n\tif strings.Contains(err.Error(), \"SearchBoardsForUserInTeam error getting unionSQL\") {\n\t\tlogger.Error(\"three-way union query build failed\", \"err\", err)\n\t\treturn nil, ErrInternalSearch\n\t}\n\treturn nil, err\n}","preventionTips":["Resolve earlier builder errors before investigating the union.","Match Suffix SQL '?' placeholders to appended args exactly.","Add rendering regression tests for the union."],"tags":["sql","squirrel","union-query","store"],"backgroundTag":"sql-build-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}