krisk/Fuse · error · Error

Pattern length exceeds max of ${max}.

Error message

Pattern length exceeds max of ${max}.

What it means

The bitap approximate-matching algorithm encodes the pattern into machine words limited to MAX_BITS (32) characters. A longer pattern makes exact bitap matching impossible, so search throws 'Pattern length exceeds max of 32.' before doing any work.

Source

Thrown at src/search/bitap/search.ts:22

import * as ErrorMsg from '../../core/errorMessages'
import type { SearchResult } from '../../types'

export default function search(
  text: string,
  pattern: string,
  patternAlphabet: Record<string, number>,
  {
    location = Config.location,
    distance = Config.distance,
    threshold = Config.threshold,
    findAllMatches = Config.findAllMatches,
    minMatchCharLength = Config.minMatchCharLength,
    includeMatches = Config.includeMatches,
    ignoreLocation = Config.ignoreLocation
  } = {}
): SearchResult {
  if (pattern.length > MAX_BITS) {
    throw new Error(ErrorMsg.PATTERN_LENGTH_TOO_LARGE(MAX_BITS))
  }

  const patternLen = pattern.length
  // Set starting location at beginning text and initialize the alphabet.
  const textLen = text.length
  // Handle the case when location > text.length
  const expectedLocation = Math.max(0, Math.min(location, textLen))
  // Highest score beyond which we give up.
  let currentThreshold = threshold
  // Is there a nearby exact match? (speedup)
  let bestLocation = expectedLocation

  // Inlined score computation — avoids object allocation per call in hot loops.
  // See ./computeScore.ts for the documented version of this formula.
  const calcScore = (errors: number, currentLocation: number): number => {
    const accuracy = errors / patternLen
    if (ignoreLocation) return accuracy
    const proximity = Math.abs(expectedLocation - currentLocation)

View on GitHub (pinned to edf2fb608e)

Solutions

  1. Truncate the query to 32 characters before searching.
  2. Split long input into tokens/words and search each term (or aggregate results).
  3. Enforce a max length on the search input UI and validate before calling search.

Example fix

// before
fuse.search(userInput) // can exceed 32 chars
// after
const pattern = userInput.slice(0, 32)
fuse.search(pattern)
Defensive patterns

Strategy: validation

Validate before calling

const MAX_BITS = 32
let pattern = userInput
if (typeof pattern === 'string' && pattern.length > MAX_BITS) {
  pattern = pattern.slice(0, MAX_BITS)
}
fuse.search(pattern)

Type guard

const isSearchablePattern = (p) => typeof p === 'string' && p.length <= 32

Try / catch

try {
  return fuse.search(query)
} catch (e) {
  if (e.message.startsWith('Pattern length exceeds max')) {
    return fuse.search(query.slice(0, 32))
  }
  throw e
}

Prevention

When it happens

Trigger: Calling bitapSearch/text search (directly or via fuse.search) with a pattern string longer than 32 characters — e.g. a whole sentence, pasted paragraph, or log line used as the query.

Common situations: Unrestricted user search boxes where users paste long text; programmatic queries built by concatenating terms; searching URLs or full lines as the pattern.


AI-assisted analysis of krisk/Fuse@edf2fb608e (2026-09-02). Data as JSON: /api/errors/f048ed233c4a4620. Report an issue: GitHub.