dmtrKovalenko/fff · critical
FFI returned null pointer
Error message
FFI returned null pointer
What it means
parseMixedSearchResult received NULL from the native fff_search_mixed symbol. readResultEnvelope could not even read an FffResult envelope, so the binding reports a null-pointer FFI failure. This indicates the native library returned no allocation at all — typically an ABI mismatch, unloaded/incompatible library, or symbol contract violation.
Solutions
- Rebuild/reinstall the native library so it matches the JS bindings (rerun the package's install/build step).
- Verify the loaded library version matches the ffi.ts bindings (same package version, no cached stale artifact).
- Check for a native crash around the call — run with debug logging or test the same call from a minimal C harness.
Example fix
// before // stale prebuilt binary after upgrading fff-bun npm install // after // force rebuild of the native artifact npm rebuild fff-bun
Defensive patterns
Strategy: try-catch
Validate before calling
if (!libraryLoaded || !library.symbols.fff_search_mixed) throw new Error('native library not loaded'); Type guard
function isResultPtr(p) { return p !== null && p !== undefined; } Try / catch
try { const r = ffiSearchMixed(handle, q); } catch (e) { if (e.message === 'FFI returned null pointer') { await rebuildNativeLib(); retry(); } } Prevention
- Keep the native binary and the JS package versions in lockstep.
- Run the package's postinstall/build step after upgrades.
- Smoke-test one FFI call at startup to detect ABI mismatch early.
When it happens
Trigger: Calling ffiSearchMixed when the loaded .so/.dylib/.dll version does not match the TypeScript bindings (struct/ABI drift), or the native code crashed/returned NULL due to an unexpected internal error.
Common situations: Stale prebuilt binary after upgrading the package (build artifacts not rebuilt); mixing bindings from one version with a native library from another; corrupted download in a postinstall step.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- fff_search_mixed returned null search result
- grep returned null 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/5ea185d6bd2d6889.
Report an issue: GitHub.
Appendix: source
Thrown at packages/fff-bun/src/ffi.ts:901
item: {
relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? "",
fileName: readCString(read.ptr(pp, MI_DISPLAY)) ?? "",
gitStatus: readCString(read.ptr(pp, MI_GIT)) ?? "",
size: Number(read.u64(pp, MI_SIZE)),
modified: Number(read.u64(pp, MI_MODIFIED)),
accessFrecencyScore: Number(read.i64(pp, MI_ACCESS)),
modificationFrecencyScore: Number(read.i64(pp, MI_MODFR)),
totalFrecencyScore: Number(read.i64(pp, MI_TOTAL_FR)),
},
};
}
/**
* Parse an FffMixedSearchResult from a raw FffResult pointer, then free native memory.
*/
function parseMixedSearchResult(resultPtr: Pointer | null): Result<MixedSearchResult> {
if (resultPtr === null) {
return err("FFI returned null pointer");
}
const envelope = readResultEnvelope(resultPtr);
if (!("success" in envelope)) return envelope;
if (envelope.handlePtr === 0) {
return err("fff_search_mixed returned null search result");
}
const hp = asPtr(envelope.handlePtr);
const count = read.u32(hp, MSR_COUNT);
const totalMatched = read.u32(hp, MSR_MATCHED);
const totalFiles = read.u32(hp, MSR_TOTAL_FILES);
const totalDirs = read.u32(hp, MSR_TOTAL_DIRS);
// Read location
const locTag = read.u8(hp, MSR_LOC_TAG);
let location: Location | undefined;View on GitHub (pinned to 7f8537e70f)