krisk/Fuse · error · Error

[Fuse] tokenize function must return string[]; received ${Ar

Error message

[Fuse] tokenize function must return string[]; received ${Array.isArray(result) ? 'array containing non-strings' : typeof result}.

What it means

Development-mode validation in resolveTokenize: a custom tokenize function returned something other than an array of strings (either a non-array or an array containing non-string tokens). The analyzer expects string[] so downstream indexing/normalization works; the error names what was received instead.

Source

Thrown at src/search/token/analyzer.ts:45

        `first match per text will be returned. Add the 'g' flag.`
    )
  }
}

function resolveTokenize(
  tokenize: RegExp | TokenizeFunction | undefined
): TokenizeFunction {
  if (typeof tokenize === 'function') {
    let validated = false
    return (text: string): string[] => {
      const result = tokenize(text)
      if (process.env.NODE_ENV === 'development' && !validated) {
        validated = true
        if (
          !Array.isArray(result) ||
          result.some((t) => typeof t !== 'string')
        ) {
          throw new Error(
            `[Fuse] tokenize function must return string[]; received ${
              Array.isArray(result)
                ? 'array containing non-strings'
                : typeof result
            }.`
          )
        }
      }
      return result
    }
  }
  if (tokenize instanceof RegExp) {
    if (!tokenize.global) warnNonGlobal(tokenize)
    return (text: string): string[] => text.match(tokenize) || []
  }
  return (text: string): string[] => text.match(DEFAULT_TOKEN) || []
}

View on GitHub (pinned to edf2fb608e)

Solutions

  1. Make the tokenize function always return string[]: return input.split(/\s+/).filter(Boolean).
  2. Coerce token elements to strings before returning (tokens.map(String)).
  3. Run in development mode during testing so this validation fires early instead of failing silently in production.
  4. Add your own return-type check or TypeScript annotation (tokenize: (s: string) => string[]) so build tooling catches it.

Example fix

// before
const tokenize = (s) => s.split(' ') // may include '' or non-strings
// after
const tokenize = (s) => s.split(/\s+/).filter(Boolean).map(String) // guarantees string[]
Defensive patterns

Strategy: type-guard

Validate before calling

const out = myTokenize(input);
if (!Array.isArray(out) || out.some((t) => typeof t !== 'string')) throw new TypeError('tokenize must return string[]');

Type guard

function isStringArray(v: unknown): v is string[] {
  return Array.isArray(v) && v.every((t) => typeof t === 'string');
}

Try / catch

try {
  const idx = new Fuse(docs, { tokenize: myTokenize });
} catch (e) {
  if (String(e.message).includes('tokenize function must return string[]')) {
    // wrap/fix the tokenizer: (s) => toTokenArray(s)
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a custom tokenize option that returns undefined, a string, a single token (not wrapped in an array), or an array containing numbers/objects — but only when NODE_ENV === 'development' and the result fails Array.isArray/result.every(typeof string) checks, via tokenizeFn.

Common situations: Writing a tokenizer that returns a string instead of splitting into an array; forgetting a .map(String) after splitting on numeric fields; refactoring a tokenizer that previously returned tokens but now returns a Promise or iterator.

Related errors


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