dmtrKovalenko/fff · error
fff_search_mixed returned null search result
Error message
fff_search_mixed returned null search result
What it means
fff_search_mixed reported success but the envelope carried a null handle, so no FffMixedSearchResult struct could be restored. The FFI layer rejects this as an invariant violation: a successful mixed search must return a result struct. Like error 60, this points to a native-side allocation or state problem, not a user input problem.
Solutions
- Ensure native library and fff-node bindings are the same version; rebuild the binary.
- Wait for the initial scan to complete (check scan progress) before issuing mixed searches.
- Retry the search once; if it consistently fails, capture the query and report a bug.
- Avoid using the finder after destroy(); recreate the instance instead.
Example fix
// before
const res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
if (!res.ok) throw new Error(res.error);
// after
const res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
if (!res.ok) {
if (res.error.includes('null search result') && (await getScanProgress()).done) {
return finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
}
throw new Error(res.error);
} Defensive patterns
Strategy: retry
Validate before calling
const progress = finder.getScanProgress();
if (progress.ok && !progress.value.done) console.warn('index still scanning; results may be incomplete'); Type guard
function canSearch(f: FileFinder | null): f is FileFinder { return f !== null && f.isAlive(); } Try / catch
const res = finder.searchMixed(opts);
if (!res.ok) {
if (res.error.includes('null search result')) return retryOnce(() => finder.searchMixed(opts));
throw new Error(res.error);
} Prevention
- Wait for the initial scan to finish before issuing searches.
- Upgrade mismatched native binaries.
- Never reuse a destroyed finder; recreate it.
- Keep memory pressure in mind for large result sets.
When it happens
Trigger: Calling FileFinder.searchMixed when the native fff_search_mixed returns success with a null handle — failed allocation of the mixed result, or the search ran against a torn-down/empty index.
Common situations: Mismatched native binary vs. bindings; searching immediately after init before indexing finished; memory pressure causing allocation failure of the result struct.
Related errors
- fff_search_directories returned null search result
- Instance handle is null. Create one with…
- opts is null
- Query is null or invalid UTF-8
- File picker not initialized. Call fff_create_instance first.
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/a8e7e9dc0ca10b55.
Report an issue: GitHub.
Appendix: source
Thrown at packages/fff-node/src/ffi.ts:1127
const [envelope] = restorePointer({
retType: [FFF_RESULT_STRUCT],
paramsValue: wrapPointer([rawPtr]),
}) as unknown as [FffResultRaw];
const success = envelope.success !== 0;
if (!success) {
const errorMsg = readCString(envelope.error) || "Unknown error";
freeResult(rawPtr);
return err(errorMsg);
}
const handlePtr = envelope.handle;
// Free the FffResult envelope (does NOT free handle)
freeResult(rawPtr);
if (isNullPointer(handlePtr)) {
return err("fff_search_mixed returned null search result");
}
// Read FffMixedSearchResult struct
const [sr] = restorePointer({
retType: [FFF_MIXED_SEARCH_RESULT_STRUCT],
paramsValue: wrapPointer([handlePtr]),
}) as unknown as [FffMixedSearchResultRaw];
const count = sr.count;
// Read location
let location: Location | undefined;
if (sr.location_tag === 1) {
location = { type: "line", line: sr.location_line };
} else if (sr.location_tag === 2) {
location = {
type: "position",
line: sr.location_line,View on GitHub (pinned to 7f8537e70f)