dmtrKovalenko/fff · error
grep returned null result
Error message
grep returned null result
What it means
parseGrepResult read a success envelope from fff_live_grep/fff_multi_grep but the result handle pointer is 0, so there is no grep result structure to parse. The binding refuses to return a fake empty result and surfaces this error instead.
Solutions
- Verify the finder instance is still alive before invoking grep (guard with ensureAlive).
- Rebuild the native library so the grep result ABI matches the bindings.
- If it persists on a valid instance with existing files, report as a native-side bug.
Example fix
// before
const r = ffiGrep(handle, pattern);
// after
if (handle === null) return err('finder destroyed');
const r = ffiGrep(handle, pattern); Defensive patterns
Strategy: try-catch
Validate before calling
if (handle === null) return err('finder destroyed before grep'); Type guard
function hasNativeHandle(f) { return f != null && typeof f.handle === 'object' && f.handle !== null; } Try / catch
try { const r = await finder.grep(pattern); } catch (e) { if (e.message.includes('grep returned null result')) return emptyGrepResult(); } Prevention
- Never call grep after destroy(); cancel timers/handlers in teardown.
- Confirm target paths exist before issuing grep.
- Rebuild native artifacts after version bumps.
When it happens
Trigger: Calling ffiGrep/ffiMultiGrep where the native grep call returns a success envelope with handlePtr === 0 — native allocation failure, destroyed instance, or an ABI/version mismatch in the grep result layout.
Common situations: Grep invoked right after destroy(); searching a directory that no longer exists with a mismatched native build; stale build artifact after upgrading.
Related errors
- FFI returned null pointer
- fff_search_mixed returned null search result
- scan progress returned null
- fff native library not found. Run `npx @ff-labs/fff-node…
- Instance handle is null. Create one with…
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/2312154e934b37e5.
Report an issue: GitHub.
Appendix: source
Thrown at packages/fff-bun/src/ffi.ts:1100
if (ctxAfterCount > 0) {
match.contextAfter = readCStringArray(read.ptr(pp, GM_CTX_AFTER), ctxAfterCount);
}
if (read.u8(pp, GM_IS_DEFINITION) !== 0) {
match.isDefinition = true;
}
return match;
}
/**
* Parse an FffGrepResult from a raw FffResult pointer, then free native memory.
*/
function parseGrepResult(resultPtr: Pointer | null): Result<GrepResult> {
const envelope = readResultEnvelope(resultPtr);
if (!("success" in envelope)) return envelope;
if (envelope.handlePtr === 0) {
return err("grep returned null result");
}
const hp = asPtr(envelope.handlePtr);
const count = read.u32(hp, GR_COUNT);
const totalMatched = read.u32(hp, GR_MATCHED);
const totalFilesSearched = read.u32(hp, GR_FILES_SEARCHED);
const totalFiles = read.u32(hp, GR_TOTAL_FILES);
const filteredFileCount = read.u32(hp, GR_FILTERED);
const nextFileOffset = read.u32(hp, GR_NEXT_OFFSET);
const regexErrPtr = read.ptr(hp, GR_REGEX_ERR);
const regexFallbackError = readCString(regexErrPtr) ?? undefined;
const itemsBase = read.ptr(hp, GR_ITEMS);
const items: GrepMatch[] = [];
for (let i = 0; i < count; i++) {
items.push(readGrepMatchStruct(itemsBase + i * GM_SIZE_OF));
}
View on GitHub (pinned to 7f8537e70f)