{"record":{"id":"6356048c2b4a764a","repo":"mattermost-community/focalboard","slug":"searchboardsforuser-error-getting-channelmemberssq","errorCode":null,"errorMessage":"SearchBoardsForUser error getting channelMembersSQL: %w","messagePattern":"SearchBoardsForUser error getting channelMembersSQL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/services/store/mattermostauthlayer/mattermostauthlayer.go","lineNumber":749,"sourceCode":"\t\t\tconditions := sq.And{}\n\t\t\tfor _, word := range strings.Split(strings.TrimSpace(term), \" \") {\n\t\t\t\tconditions = append(conditions, sq.Like{\"lower(b.title)\": \"%\" + strings.ToLower(word) + \"%\"})\n\t\t\t}\n\n\t\t\tboardMembersQ = boardMembersQ.Where(conditions)\n\t\t\tteamMembersQ = teamMembersQ.Where(conditions)\n\t\t\tchannelMembersQ = channelMembersQ.Where(conditions)\n\t\t}\n\t}\n\n\tteamMembersSQL, teamMembersArgs, err := teamMembersQ.ToSql()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SearchBoardsForUser error getting teamMembersSQL: %w\", err)\n\t}\n\n\tchannelMembersSQL, channelMembersArgs, err := channelMembersQ.ToSql()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SearchBoardsForUser error getting channelMembersSQL: %w\", err)\n\t}\n\n\tunionQ := boardMembersQ\n\tuser, err := s.GetUserByID(userID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// NOTE: theoretically, could do e.g. `isGuest := !includePublicBoards`\n\t// but that introduces some tight coupling + fragility\n\tif !user.IsGuest {\n\t\tunionQ = unionQ.\n\t\t\tPrefix(\"(\").\n\t\t\tSuffix(\") UNION (\"+channelMembersSQL+\")\", channelMembersArgs...)\n\t\tif includePublicBoards {\n\t\t\tunionQ = unionQ.Suffix(\" UNION (\"+teamMembersSQL+\")\", teamMembersArgs...)\n\t\t}\n\t} else if includePublicBoards {\n\t\tunionQ = unionQ.","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/mattermost-community/focalboard/blob/a84bbb65e32edf972856b329417096ac413518e9/server/services/store/mattermostauthlayer/mattermostauthlayer.go#L731-L767","documentation":"Same class as error 82 but for channelMembersQ: the channel-members SelectBuilder in SearchBoardsForUser could not be converted to SQL by squirrel's ToSql(). The query was structurally invalid at conversion time.","triggerScenarios":"channelMembersQ.ToSql() fails after the conditional Where(conditions) block — invalid placeholder combination or builder missing required clauses.","commonSituations":"A code path where channelMembersQ is built only under certain membership conditions and reaches ToSql() unpopulated; squirrel upgrade changing ToSql() strictness; malformed search parameters.","solutions":["Review the channelMembersQ construction (lines above 749) and guarantee SELECT/FROM clauses are always set.","Log the built conditions when the error occurs to identify the malformed branch.","Pin the squirrel version and check for regressions after dependency updates.","Cover the channel-members path with unit tests including the empty-conditions case."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"boards, err := store.SearchBoardsForUser(userID, term)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error getting channelMembersSQL\") {\n\t\tlogger.Error(\"channel members query build failed\", \"err\", err)\n\t\treturn nil, ErrInternalSearch\n\t}\n\treturn nil, err\n}","preventionTips":["Ensure channelMembersQ is fully built on every code path before ToSql().","Test the search path with empty conditions and with channel filters.","Keep squirrel dependency versions consistent across modules."],"tags":["sql","squirrel","query-builder","store"],"backgroundTag":"sql-build-failed","analyzedSha":"a84bbb65e32edf972856b329417096ac413518e9","analyzedAt":"2026-08-30T09:22:20.720Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}