medusajs/medusa · error · MedusaError

Medusa search accepts at most ${MAX_MULTI_QUERIES} queries p

Error message

Medusa search accepts at most ${MAX_MULTI_QUERIES} queries per multi-query; this search needs ${queries.length}

What it means

The Medusa search provider caps how many individual queries a single multi-query request can contain. Every facet range, facet value, and the main query counts toward MAX_MULTI_QUERIES, and this error is thrown when the assembled multi-query batch exceeds that provider limit.

Source

Thrown at packages/modules/search/src/providers/search-medusa/services/medusa-search.ts:235

  ): Promise<SearchTypes.SearchResult> {
    const plan = buildIndexPlan(input.index)
    const base = buildQueryPlan(input, plan)
    const facets = buildFacetQueries(input, plan)
    const includeCount = input.search_options?.count !== "none"
    const queries: IndexQuery[] = [base.query]
    const countIndex = includeCount ? queries.length : -1

    if (includeCount) {
      queries.push({
        aggregate_by: { count: ["Count"] },
        filters: base.query.filters,
      })
    }
    const facetOffset = queries.length
    queries.push(...facets.map((facet) => facet.query))

    if (queries.length > MAX_MULTI_QUERIES) {
      throw new MedusaError(
        MedusaError.Types.NOT_ALLOWED,
        `Medusa search accepts at most ${MAX_MULTI_QUERIES} queries per multi-query; this search needs ${queries.length}`
      )
    }

    const response = await this.index(input.index.physical_name).multiQuery({
      queries,
      consistency: base.options.consistency
        ? { level: base.options.consistency }
        : undefined,
    })
    const hitResult = response.results[0]
    const rows = (hitResult?.rows ?? []).slice(base.skip, base.skip + base.take)
    const parsedFacets = parseFacetResults(
      facets,
      response.results.slice(facetOffset)
    )

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Reduce the number of facet requests in search_options.facets (drop unused facets or fetch them across separate searches)
  2. If using range facets, consolidate range buckets so each facet contributes fewer sub-queries
  3. Precompute total query count (1 + sum of ranges + value facets) and cap it client-side before calling search

Example fix

// before
const result = await query.graph({
  entity: "product",
  filters: { q: "shirt" },
  pagination: {},
  // ...options with many facets
})
// limit facets / range buckets
const facets = [...allFacets].slice(0, 5)
Defensive patterns

Strategy: validation

Validate before calling

const MAX_MULTI_QUERIES = 50 // keep in sync with provider constant
function estimateQueryCount(facets) {
  return (
    1 +
    facets.reduce(
      (n, f) => n + (f.type === "range" ? f.ranges.length : 1),
      0
    )
  )
}
if (estimateQueryCount(facets) > MAX_MULTI_QUERIES) {
  facets = facets.slice(0, MAX_MULTI_QUERIES - 1)
}

Type guard

const isFacetRequest = (f) =>
  typeof f?.field === "string" &&
  (f.type === "range" ? Array.isArray(f.ranges) && f.ranges.length > 0 : true)

Try / catch

try { await search(...) } catch (e) { if (e instanceof MedusaError && e.type === "not_allowed" && /at most/.test(e.message)) { /* drop facets and retry once without facets */ } throw e }

Prevention

When it happens

Trigger: Calling searchMany (or the provider search path that fans out into a multiQuery) with many facet requests, especially range facets that expand into one query per range bucket, plus additional facet value queries, so queries.length > MAX_MULTI_QUERIES.

Common situations: Storefront filter UIs requesting many range buckets (e.g. price ranges sliced into many intervals) or large numbers of faceted fields in one search request; copying a Meilisearch-style facet config with dozens of facets into search_options.facets.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/a99331071bfaf95b. Report an issue: GitHub.