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
- Verify the index name in the query matches an index defined in your search module index settings
- Ensure every queried field is declared in the index settings and regenerate/rebuild the index so the table and plan exist
- For vector queries, configure an embedding field and a supported vector_distance option
- 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
- Keep index names in a typed constant union instead of raw strings
- Rebuild/generate indexes after changing index settings
- Run a health check on startup that queries each index once
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.