{"record":{"id":"a8e7e9dc0ca10b55","repo":"dmtrKovalenko/fff","slug":"fff-search-mixed-returned-null-search-result-a8e7e9","errorCode":null,"errorMessage":"fff_search_mixed returned null search result","messagePattern":"fff_search_mixed returned null search result","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/fff-node/src/ffi.ts","lineNumber":1127,"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_mixed returned null search result\");\n  }\n\n  // Read FffMixedSearchResult struct\n  const [sr] = restorePointer({\n    retType: [FFF_MIXED_SEARCH_RESULT_STRUCT],\n    paramsValue: wrapPointer([handlePtr]),\n  }) as unknown as [FffMixedSearchResultRaw];\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":1109,"sourceCodeEnd":1145,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/packages/fff-node/src/ffi.ts#L1109-L1145","documentation":"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.","triggerScenarios":"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.","commonSituations":"Mismatched native binary vs. bindings; searching immediately after init before indexing finished; memory pressure causing allocation failure of the result struct.","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."],"exampleFix":"// before\nconst res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });\nif (!res.ok) throw new Error(res.error);\n// after\nconst res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });\nif (!res.ok) {\n  if (res.error.includes('null search result') && (await getScanProgress()).done) {\n    return finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });\n  }\n  throw new Error(res.error);\n}","handlingStrategy":"retry","validationCode":"const progress = finder.getScanProgress();\nif (progress.ok && !progress.value.done) console.warn('index still scanning; results may be incomplete');","typeGuard":"function canSearch(f: FileFinder | null): f is FileFinder { return f !== null && f.isAlive(); }","tryCatchPattern":"const res = finder.searchMixed(opts);\nif (!res.ok) {\n  if (res.error.includes('null search result')) return retryOnce(() => finder.searchMixed(opts));\n  throw new Error(res.error);\n}","preventionTips":["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."],"tags":["ffi","native","null-pointer"],"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"}