medusajs/medusa · error · MedusaError

${message}

Error message

${message}

What it means

Thrown by the search-postgres module's planning utilities (fieldKind, walk, assertQuerySupported, tableNameForIndex) when a query or field definition cannot be planned: an unknown field kind, an unsupported query shape, or an index without a resolvable physical table. The fail() helper raises MedusaError NOT_ALLOWED with a descriptive message.

Source

Thrown at packages/modules/providers/search-postgres/src/utils/plan.ts:67

   * - `native` — portable Postgres FTS (GIN + `ts_rank`) + `pg_trgm`. Default.
   * - `lakebase` — Lakebase Search (`lakebase_text` BM25 + `lakebase_vector` ANN).
   * @default "native"
   */
  engine?: PostgresSearchEngine
  /**
   * Embeds text for `search_options.vector.query`. Required on the lakebase
   * engine when callers pass a query string instead of a pre-computed `value`.
   */
  embedder?: PostgresSearchEmbedder
  /**
   * Distance metric for `lakebase_ann` / pgvector indexes.
   * @default "cosine"
   */
  vector_distance?: PostgresVectorDistance
}

function fail(message: string): never {
  throw new MedusaError(MedusaError.Types.NOT_ALLOWED, message)
}

export function isSearchable(
  field: SearchTypes.SearchFieldDefinition
): boolean {
  return field.searchable === true || typeof field.searchable === "object"
}

export function isFacetable(field: SearchTypes.SearchFieldDefinition): boolean {
  return field.facetable === true || typeof field.facetable === "object"
}

function fieldKind(
  field: SearchTypes.SearchFieldDefinition
): PostgresFieldKind {
  switch (field.type) {
    case "text":
      return "text"

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Verify the index name in the query matches an index defined in your search module index settings
  2. Ensure every queried field is declared in the index settings and regenerate/rebuild the index so the table and plan exist
  3. For vector queries, configure an embedding field and a supported vector_distance option
  4. Re-run the index creation/migration flow for the search-postgres provider after settings changes

Example fix

// before
await searchService.search({ index: "produtcs", q: "shirt" }) // typo: no table
// after
await searchService.search({ index: "products", q: "shirt" })
Defensive patterns

Strategy: validation

Validate before calling

const definedIndexes = await searchModule.indexes() // or from settings
const indexNames = new Set(definedIndexes.map((i) => i.name))
if (!indexNames.has(requestedIndex)) {
  throw new Error(`Unknown index: ${requestedIndex}`)
}

Type guard

function isKnownIndex(index: string, known: string[]): index is KnownIndexName {
  return known.includes(index)
}

Try / catch

try {
  await searchModule.search(args)
} catch (e) {
  if (e instanceof MedusaError && e.type === MedusaError.Types.NOT_ALLOWED) {
    // plan-level rejection: verify index settings & rebuild index
    await searchModule.syncIndex(requestedIndex).catch(() => {})
  } else throw e
}

Prevention

When it happens

Trigger: Querying an index name that has no generated backing table, querying a field whose kind cannot be determined from the index settings, or issuing a query mode (e.g. vector search without a configured embedding) that assertQuerySupported rejects.

Common situations: Index settings changed (fields renamed/removed) without re-running index generation, naming mismatch between the index used at query time and the one defined in settings, enabling vector query options without configuring an embedding field/distance, or upgrading search-postgres with breaking plan changes.

Related errors


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