{"record":{"id":"8cf837d36baacf15","repo":"instructure/canvas-lms","slug":"search-term-must-be-at-least-searchtermhelper-min-search-8cf837","errorCode":null,"errorMessage":"search term must be at least #{SearchTermHelper::MIN_SEARCH_TERM_LENGTH} characters","messagePattern":"search term must be at least #(.+?) characters","errorType":"validation","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"warning","filePath":"app/graphql/types/course_type.rb","lineNumber":126,"sourceCode":"               required: false\n      argument :search_term,\n               String,\n               <<~MD,\n                 Only return users that match the given search term. The search\n                 term is matched against the user's name and depending on current\n                 user permissions against the user's login id, email and sisid\n               MD\n               required: false,\n               prepare: :prepare_search_term\n      argument :user_ids,\n               [ID],\n               \"only include users with the given ids\",\n               prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func(\"User\"),\n               required: false\n\n      def prepare_search_term(term)\n        if term.presence && term.length < SearchTermHelper::MIN_SEARCH_TERM_LENGTH\n          raise GraphQL::ExecutionError, \"search term must be at least #{SearchTermHelper::MIN_SEARCH_TERM_LENGTH} characters\"\n        end\n\n        term\n      end\n    end\n\n    class CourseSectionsFilterInputType < Types::BaseInputObject\n      graphql_name \"CourseSectionsFilter\"\n\n      argument :assignment_id,\n               ID,\n               \"Only include sections associated with users assigned to this assignment\",\n               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func(\"Assignment\"),\n               required: false\n    end\n\n    implements GraphQL::Types::Relay::Node\n    implements Interfaces::TimestampInterface","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/types/course_type.rb#L108-L144","documentation":"CourseType.userSearch (users_connection) prepare_search_term hook. The search argument on Course.users must be at least SearchTermHelper::MIN_SEARCH_TERM_LENGTH characters; shorter non-blank terms raise GraphQL::ExecutionError before any user lookup happens.","triggerScenarios":"Querying course.users with search: \"ab\" (shorter than the minimum) — the prepare hook fires during argument coercion.","commonSituations":"Course roster search UIs sending partial input; integrations guessing a minimum; automated tests using tiny search strings.","solutions":["Pad/extend the search term to meet SearchTermHelper::MIN_SEARCH_TERM_LENGTH","Add client-side validation mirroring the minimum length","Use the user_ids argument instead of search when filtering by id"],"exampleFix":"// before\nusers(search: \"jo\") { ... }\n// after\nusers(search: \"jose\") { ... }","handlingStrategy":"validation","validationCode":"if (!search || search.length >= MIN_SEARCH_TERM_LENGTH) queryCourseUsers({ search })","typeGuard":"function searchOk(term, min) { return term == null || term.length >= min }","tryCatchPattern":null,"preventionTips":["Gate roster search UIs on minimum length","Prefer user_ids filtering when ids are known","Document the server minimum in the client API layer"],"tags":["graphql","input-validation","search"],"backgroundTag":"value-out-of-range","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}