{"record":{"id":"f048ed233c4a4620","repo":"krisk/Fuse","slug":"pattern-length-exceeds-max-of-max","errorCode":null,"errorMessage":"Pattern length exceeds max of ${max}.","messagePattern":"Pattern length exceeds max of (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/search/bitap/search.ts","lineNumber":22,"sourceCode":"import * as ErrorMsg from '../../core/errorMessages'\nimport type { SearchResult } from '../../types'\n\nexport default function search(\n  text: string,\n  pattern: string,\n  patternAlphabet: Record<string, number>,\n  {\n    location = Config.location,\n    distance = Config.distance,\n    threshold = Config.threshold,\n    findAllMatches = Config.findAllMatches,\n    minMatchCharLength = Config.minMatchCharLength,\n    includeMatches = Config.includeMatches,\n    ignoreLocation = Config.ignoreLocation\n  } = {}\n): SearchResult {\n  if (pattern.length > MAX_BITS) {\n    throw new Error(ErrorMsg.PATTERN_LENGTH_TOO_LARGE(MAX_BITS))\n  }\n\n  const patternLen = pattern.length\n  // Set starting location at beginning text and initialize the alphabet.\n  const textLen = text.length\n  // Handle the case when location > text.length\n  const expectedLocation = Math.max(0, Math.min(location, textLen))\n  // Highest score beyond which we give up.\n  let currentThreshold = threshold\n  // Is there a nearby exact match? (speedup)\n  let bestLocation = expectedLocation\n\n  // Inlined score computation — avoids object allocation per call in hot loops.\n  // See ./computeScore.ts for the documented version of this formula.\n  const calcScore = (errors: number, currentLocation: number): number => {\n    const accuracy = errors / patternLen\n    if (ignoreLocation) return accuracy\n    const proximity = Math.abs(expectedLocation - currentLocation)","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/krisk/Fuse/blob/edf2fb608eca0461508d1d71317e6e58309ffada/src/search/bitap/search.ts#L4-L40","documentation":"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.","triggerScenarios":"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.","commonSituations":"Unrestricted user search boxes where users paste long text; programmatic queries built by concatenating terms; searching URLs or full lines as the pattern.","solutions":["Truncate the query to 32 characters before searching.","Split long input into tokens/words and search each term (or aggregate results).","Enforce a max length on the search input UI and validate before calling search."],"exampleFix":"// before\nfuse.search(userInput) // can exceed 32 chars\n// after\nconst pattern = userInput.slice(0, 32)\nfuse.search(pattern)","handlingStrategy":"validation","validationCode":"const MAX_BITS = 32\nlet pattern = userInput\nif (typeof pattern === 'string' && pattern.length > MAX_BITS) {\n  pattern = pattern.slice(0, MAX_BITS)\n}\nfuse.search(pattern)","typeGuard":"const isSearchablePattern = (p) => typeof p === 'string' && p.length <= 32","tryCatchPattern":"try {\n  return fuse.search(query)\n} catch (e) {\n  if (e.message.startsWith('Pattern length exceeds max')) {\n    return fuse.search(query.slice(0, 32))\n  }\n  throw e\n}","preventionTips":["Clamp or tokenize user search input before searching.","Enforce a max length on search input fields.","Split long phrases into words and aggregate results."],"tags":["pattern-length","bitap","input-validation"],"backgroundTag":"pattern-length-exceeds-max","analyzedSha":"edf2fb608eca0461508d1d71317e6e58309ffada","analyzedAt":"2026-09-02T02:46:54.623Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}