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
- Make the tokenize function always return string[]: return input.split(/\s+/).filter(Boolean).
- Coerce token elements to strings before returning (tokens.map(String)).
- Run in development mode during testing so this validation fires early instead of failing silently in production.
- 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
- Annotate tokenizers as (s: string) => string[] in TypeScript
- Run the app in NODE_ENV=development during tests to trigger validation
- Always .map(String) and filter empties before returning tokens
- Never return a Promise or iterator from tokenize
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.