{"record":{"id":"5ea185d6bd2d6889","repo":"dmtrKovalenko/fff","slug":"ffi-returned-null-pointer","errorCode":null,"errorMessage":"FFI returned null pointer","messagePattern":"FFI returned null pointer","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/fff-bun/src/ffi.ts","lineNumber":901,"sourceCode":"    item: {\n      relativePath: readCString(read.ptr(pp, MI_RELPATH)) ?? \"\",\n      fileName: readCString(read.ptr(pp, MI_DISPLAY)) ?? \"\",\n      gitStatus: readCString(read.ptr(pp, MI_GIT)) ?? \"\",\n      size: Number(read.u64(pp, MI_SIZE)),\n      modified: Number(read.u64(pp, MI_MODIFIED)),\n      accessFrecencyScore: Number(read.i64(pp, MI_ACCESS)),\n      modificationFrecencyScore: Number(read.i64(pp, MI_MODFR)),\n      totalFrecencyScore: Number(read.i64(pp, MI_TOTAL_FR)),\n    },\n  };\n}\n\n/**\n * Parse an FffMixedSearchResult from a raw FffResult pointer, then free native memory.\n */\nfunction parseMixedSearchResult(resultPtr: Pointer | null): Result<MixedSearchResult> {\n  if (resultPtr === null) {\n    return err(\"FFI returned null pointer\");\n  }\n\n  const envelope = readResultEnvelope(resultPtr);\n  if (!(\"success\" in envelope)) return envelope;\n\n  if (envelope.handlePtr === 0) {\n    return err(\"fff_search_mixed returned null search result\");\n  }\n\n  const hp = asPtr(envelope.handlePtr);\n  const count = read.u32(hp, MSR_COUNT);\n  const totalMatched = read.u32(hp, MSR_MATCHED);\n  const totalFiles = read.u32(hp, MSR_TOTAL_FILES);\n  const totalDirs = read.u32(hp, MSR_TOTAL_DIRS);\n\n  // Read location\n  const locTag = read.u8(hp, MSR_LOC_TAG);\n  let location: Location | undefined;","sourceCodeStart":883,"sourceCodeEnd":919,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/fff-bun/src/ffi.ts#L883-L919","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// stale prebuilt binary after upgrading fff-bun\nnpm install\n// after\n// force rebuild of the native artifact\nnpm rebuild fff-bun","handlingStrategy":"try-catch","validationCode":"if (!libraryLoaded || !library.symbols.fff_search_mixed) throw new Error('native library not loaded');","typeGuard":"function isResultPtr(p) { return p !== null && p !== undefined; }","tryCatchPattern":"try { const r = ffiSearchMixed(handle, q); } catch (e) { if (e.message === 'FFI returned null pointer') { await rebuildNativeLib(); retry(); } }","preventionTips":["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."],"tags":["ffi","null-pointer","bun","abi-mismatch"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"7f8537e70f0ea1210f9acbbfc4640141105cdc78","analyzedAt":"2026-09-10T07:26:53.407Z","contentChangedAt":"2026-09-10T07:26:53.407Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}