dmtrKovalenko/fff · error

fff_search_mixed returned null search result

Error message

fff_search_mixed returned null search result

What it means

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.

Solutions

  1. Ensure native library and fff-node bindings are the same version; rebuild the binary.
  2. Wait for the initial scan to complete (check scan progress) before issuing mixed searches.
  3. Retry the search once; if it consistently fails, capture the query and report a bug.
  4. Avoid using the finder after destroy(); recreate the instance instead.

Example fix

// before
const res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
if (!res.ok) throw new Error(res.error);
// after
const res = finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
if (!res.ok) {
  if (res.error.includes('null search result') && (await getScanProgress()).done) {
    return finder.searchMixed({ query: 'foo', kinds: ['file','dir'] });
  }
  throw new Error(res.error);
}
Defensive patterns

Strategy: retry

Validate before calling

const progress = finder.getScanProgress();
if (progress.ok && !progress.value.done) console.warn('index still scanning; results may be incomplete');

Type guard

function canSearch(f: FileFinder | null): f is FileFinder { return f !== null && f.isAlive(); }

Try / catch

const res = finder.searchMixed(opts);
if (!res.ok) {
  if (res.error.includes('null search result')) return retryOnce(() => finder.searchMixed(opts));
  throw new Error(res.error);
}

Prevention

When it happens

Trigger: 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.

Common situations: Mismatched native binary vs. bindings; searching immediately after init before indexing finished; memory pressure causing allocation failure of the result struct.

Related errors


AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10). Data as JSON: /api/errors/a8e7e9dc0ca10b55. Report an issue: GitHub.

Appendix: source

Thrown at packages/fff-node/src/ffi.ts:1127

  const [envelope] = restorePointer({
    retType: [FFF_RESULT_STRUCT],
    paramsValue: wrapPointer([rawPtr]),
  }) as unknown as [FffResultRaw];

  const success = envelope.success !== 0;

  if (!success) {
    const errorMsg = readCString(envelope.error) || "Unknown error";
    freeResult(rawPtr);
    return err(errorMsg);
  }

  const handlePtr = envelope.handle;
  // Free the FffResult envelope (does NOT free handle)
  freeResult(rawPtr);

  if (isNullPointer(handlePtr)) {
    return err("fff_search_mixed returned null search result");
  }

  // Read FffMixedSearchResult struct
  const [sr] = restorePointer({
    retType: [FFF_MIXED_SEARCH_RESULT_STRUCT],
    paramsValue: wrapPointer([handlePtr]),
  }) as unknown as [FffMixedSearchResultRaw];

  const count = sr.count;

  // Read location
  let location: Location | undefined;
  if (sr.location_tag === 1) {
    location = { type: "line", line: sr.location_line };
  } else if (sr.location_tag === 2) {
    location = {
      type: "position",
      line: sr.location_line,

View on GitHub (pinned to 7f8537e70f)