medusajs/medusa · error · MedusaError
${message}
Error message
${message} What it means
This is the facet-building error channel of the search-medusa provider: buildFacetQueries calls fail() with a NOT_ALLOWED MedusaError for facet requests the provider cannot serve. Known messages: 'Unknown facet field "<name>"' (field not in the index plan) and rejection of type "stats" facets because the cloud service does not expose min/max aggregates.
Source
Thrown at packages/modules/search/src/providers/search-medusa/utils/facets.ts:31
{ type: "range" }
>
type ValueFacetRequest = {
field: string
type?: "value"
limit?: number
sort?: "count" | "alpha"
query?: string
}
export type FacetQuery = {
field: string
request: RangeFacetRequest | ValueFacetRequest
range?: RangeFacetRequest["ranges"][number]
query: IndexQuery
}
function fail(message: string): never {
throw new MedusaError(MedusaError.Types.NOT_ALLOWED, message)
}
function and(filters: (Filter | undefined)[]): Filter | undefined {
const present = filters.filter((item): item is Filter => !!item)
if (!present.length) {
return undefined
}
return present.length === 1 ? present[0] : ["And", present]
}
export function buildFacetQueries(
input: SearchTypes.ProviderSearchQuery,
plan: IndexPlan
): FacetQuery[] {
const requests = (input.search_options?.facets ?? []) as
| SearchTypes.SearchFacetRequest[]
const base = toSearchFilter(input.filters, plan)
const result: FacetQuery[] = []View on GitHub (pinned to 5e06e544a2)
Solutions
- Only request facet fields that exist in the index plan/definition; add the missing field as facetable in the index settings
- Replace stats facets with range facets (e.g. explicit price buckets), which the provider supports
- Keep the storefront facet list in sync with the index schema after model changes
Example fix
// before
search_options: { facets: [{ field: "price", type: "stats" }] }
// after
search_options: {
facets: [
{
field: "price",
type: "range",
ranges: [{ to: 50 }, { from: 50, to: 100 }, { from: 100 }],
},
],
}
Defensive patterns
Strategy: validation
Validate before calling
const indexFields = new Set([...]) // derived from index definition const safeFacets = requestedFacets.filter( (f) => indexFields.has(f.field) && f.type !== "stats" )
Type guard
const isSupportedFacet = (f, indexFields) => indexFields.has(f.field) && f.type !== "stats" && (f.type !== "range" || Array.isArray(f.ranges))
Try / catch
try { await search(...) } catch (e) { if (e instanceof MedusaError && e.type === "not_allowed" && /facet/i.test(e.message)) { return search(..., { facets: [] }) } throw e } Prevention
- Derive the storefront facet list from the index definition, not hardcoded strings
- Use range facets instead of stats facets
- Re-sync facet configs whenever index settings change
When it happens
Trigger: Passing a facet request in search_options.facets referencing a field not defined in the index schema (or not facetable/planned), or sending { type: "stats" } facets, which the Medusa cloud service cannot compute.
Common situations: Requesting facets on a field that exists on the model but was not added to the index definition; renaming/removing an index field while the storefront still requests the old facet; migrating a storefront from Meilisearch-style stats facets (price min/max) to Medusa search.
Related errors
- Medusa search accepts at most ${MAX_MULTI_QUERIES} queries p
- ${message}
- ${message}
- Deleting Medusa search documents requires filters
- A Medusa search document exceeds the ${MAX_WRITE_BYTES}-byte
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/24f97a206b7b5dce.
Report an issue: GitHub.