instructure/canvas-lms · warning · GraphQL::ExecutionError

search term must be at least #

Error message

search term must be at least #{SearchTermHelper::MIN_SEARCH_TERM_LENGTH} characters

What it means

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.

Solutions

  1. Pad/extend the search term to meet SearchTermHelper::MIN_SEARCH_TERM_LENGTH
  2. Add client-side validation mirroring the minimum length
  3. Use the user_ids argument instead of search when filtering by id

Example fix

// before
users(search: "jo") { ... }
// after
users(search: "jose") { ... }
Defensive patterns

Strategy: validation

Validate before calling

if (!search || search.length >= MIN_SEARCH_TERM_LENGTH) queryCourseUsers({ search })

Type guard

function searchOk(term, min) { return term == null || term.length >= min }

Prevention

When it happens

Trigger: Querying course.users with search: "ab" (shorter than the minimum) — the prepare hook fires during argument coercion.

Common situations: Course roster search UIs sending partial input; integrations guessing a minimum; automated tests using tiny search strings.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/8cf837d36baacf15. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/types/course_type.rb:126

               required: false
      argument :search_term,
               String,
               <<~MD,
                 Only return users that match the given search term. The search
                 term is matched against the user's name and depending on current
                 user permissions against the user's login id, email and sisid
               MD
               required: false,
               prepare: :prepare_search_term
      argument :user_ids,
               [ID],
               "only include users with the given ids",
               prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func("User"),
               required: false

      def prepare_search_term(term)
        if term.presence && term.length < SearchTermHelper::MIN_SEARCH_TERM_LENGTH
          raise GraphQL::ExecutionError, "search term must be at least #{SearchTermHelper::MIN_SEARCH_TERM_LENGTH} characters"
        end

        term
      end
    end

    class CourseSectionsFilterInputType < Types::BaseInputObject
      graphql_name "CourseSectionsFilter"

      argument :assignment_id,
               ID,
               "Only include sections associated with users assigned to this assignment",
               prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("Assignment"),
               required: false
    end

    implements GraphQL::Types::Relay::Node
    implements Interfaces::TimestampInterface

View on GitHub (pinned to 1c9f0bb801)