{"record":{"id":"995b8db23d9222d7","repo":"dmtrKovalenko/fff","slug":"fff-search-returned-null-search-result","errorCode":null,"errorMessage":"fff_search returned null search result","messagePattern":"fff_search returned null search result","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/fff-node/src/ffi.ts","lineNumber":952,"sourceCode":"  const [envelope] = restorePointer({\n    retType: [FFF_RESULT_STRUCT],\n    paramsValue: wrapPointer([rawPtr]),\n  }) as unknown as [FffResultRaw];\n\n  const success = envelope.success !== 0;\n\n  if (!success) {\n    const errorMsg = readCString(envelope.error) || \"Unknown error\";\n    freeResult(rawPtr);\n    return err(errorMsg);\n  }\n\n  const handlePtr = envelope.handle;\n  // Free the FffResult envelope (does NOT free handle)\n  freeResult(rawPtr);\n\n  if (isNullPointer(handlePtr)) {\n    return err(\"fff_search returned null search result\");\n  }\n\n  // Read FffSearchResult struct\n  const [sr] = restorePointer({\n    retType: [FFF_SEARCH_RESULT_STRUCT],\n    paramsValue: wrapPointer([handlePtr]),\n  }) as unknown as [FffSearchResultRaw];\n\n  const count = sr.count;\n\n  // Read location\n  let location: Location | undefined;\n  if (sr.location_tag === 1) {\n    location = { type: \"line\", line: sr.location_line };\n  } else if (sr.location_tag === 2) {\n    location = {\n      type: \"position\",\n      line: sr.location_line,","sourceCodeStart":934,"sourceCodeEnd":970,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/fff-node/src/ffi.ts#L934-L970","documentation":"In the FFI result-unwrapping path for fff_search, the Rust side returns an FffResult envelope whose success flag indicates completion, but its handle field points to the actual FffSearchResult. When success is set yet the handle is null, the envelope contains no usable search result, so this error is raised instead of proceeding to read the struct. It effectively means the native search call completed but failed to produce a result object (e.g. the Rust layer returned a success envelope with an uninitialized/null handle), and the Node wrapper converts it into an err value so callers never see a dangling or empty handle.","triggerScenarios":"Native allocation failure while building the search result; ABI/struct layout mismatch between JS bindings and the compiled shared library; internal invariant violation in the Rust search path.","commonSituations":"Running a prebuilt binary that doesn't match the installed JS package version; low-memory environments where native allocation fails.","solutions":["Rebuild or reinstall the native library to match the JS version (make build)","Retry the search; recreate the finder instance if it persists","Pin package and native binary to the same released version"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"const res = finder.search(query); if (!res.ok && res.error.includes('null search result')) { /* rebuild native lib / recreate instance */ }","preventionTips":["Keep bindings and binary versions aligned","Deploy only on supported platforms/arches","Recreate instances after repeated FFI failures"],"tags":["node","ffi","null-handle"],"backgroundTag":"null-argument","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"}