medusajs/medusa · error · MedusaError

A Medusa search document exceeds the ${MAX_WRITE_BYTES}-byte

Error message

A Medusa search document exceeds the ${MAX_WRITE_BYTES}-byte provider limit

What it means

When upserting documents, each row is serialized to JSON and must fit within MAX_WRITE_BYTES on its own. A single document larger than that byte limit cannot be chunked and triggers this INVALID_DATA error.

Source

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

      },
    }
  }

  async searchMany(
    inputs: SearchTypes.ProviderSearchQuery[]
  ): Promise<SearchTypes.SearchResult[]> {
    return await Promise.all(inputs.map((input) => this.search(input)))
  }

  protected chunkRows(rows: Row[]): Row[][] {
    const chunks: Row[][] = []
    let chunk: Row[] = []
    let bytes = 0

    for (const row of rows) {
      const rowBytes = Buffer.byteLength(JSON.stringify(row), "utf8")
      if (rowBytes > MAX_WRITE_BYTES) {
        throw new MedusaError(
          MedusaError.Types.INVALID_DATA,
          `A Medusa search document exceeds the ${MAX_WRITE_BYTES}-byte provider limit`
        )
      }
      if (chunk.length && bytes + rowBytes > MAX_WRITE_BYTES) {
        chunks.push(chunk)
        chunk = []
        bytes = 0
      }
      chunk.push(row)
      bytes += rowBytes
    }

    if (chunk.length) {
      chunks.push(chunk)
    }
    return chunks
  }

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Trim or truncate oversized text fields (e.g. long descriptions) before indexing
  2. Split huge nested arrays (variants, metadata) or stop indexing the bloated field via the index field settings
  3. Sanitize documents pre-upload: JSON.stringify and check byte length, and reduce/omit the offending field

Example fix

// before
await searchModuleService.upsertDocuments(indexName, products)
// after - prune heavy fields before indexing
const slim = products.map((p) => ({
  ...p,
  description: p.description?.slice(0, 10_000),
  metadata: undefined,
}))
await searchModuleService.upsertDocuments(indexName, slim)
Defensive patterns

Strategy: validation

Validate before calling

const MAX_WRITE_BYTES = 10 * 1024 * 1024 // match provider constant
function pruneForIndex(doc) {
  const clone = { ...doc }
  for (const k of ["metadata", "description"]) {
    if (clone[k] && Buffer.byteLength(JSON.stringify(clone[k]), "utf8") > 100_000) {
      delete clone[k]
    }
  }
  return Buffer.byteLength(JSON.stringify(clone), "utf8") <= MAX_WRITE_BYTES
    ? clone
    : null
}

Type guard

const isWithinWriteLimit = (doc) =>
  Buffer.byteLength(JSON.stringify(doc), "utf8") <= MAX_WRITE_BYTES

Try / catch

try { await upsertDocuments(index, docs) } catch (e) { if (e instanceof MedusaError && /provider limit/.test(e.message)) { /* split or truncate the offending document, then re-upsert the rest */ } throw e }

Prevention

When it happens

Trigger: upsertDocuments (e.g. via search module index sync or a reindex) receives at least one row whose JSON.stringify byte length exceeds MAX_WRITE_BYTES — typically a product with huge description text, very long variant lists, or a large embedded vector/blob.

Common situations: Indexing products with big HTML descriptions, thousands of variants/options, or AI-generated vectors attached to documents; migrating from another provider with no document size cap and reindexing existing catalog data.

Related errors


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