dmtrKovalenko/fff · error
scan progress returned null
Error message
scan progress returned null
What it means
ffiGetScanProgress received a success envelope from fff_get_scan_progress whose handle pointer is 0, meaning the native side returned no ScanProgress struct. The binding maps this to an error instead of defaulting the progress fields.
Solutions
- Stop polling scan progress once the instance is destroyed; guard the call with an aliveness check.
- Only call fff_get_scan_progress with the handle returned by instance creation, kept valid until teardown.
- Rebuild the native library if the error occurs on a live instance.
Example fix
// before
setInterval(() => ffiGetScanProgress(handle), 500); // keeps polling after destroy()
// after
setInterval(() => { if (handle !== null) ffiGetScanProgress(handle); }, 500); Defensive patterns
Strategy: type-guard
Validate before calling
if (finderHandle === null) return { scannedFilesCount: 0, isScanning: false }; Type guard
function canPollProgress(finder) { return finder != null && finder.handle !== null; } Try / catch
try { const p = await finder.getScanProgress(); } catch (e) { if (e.message.includes('scan progress returned null')) stopProgressPolling(); } Prevention
- Stop progress timers in the destroy() path.
- Only poll progress with the live handle from instance creation.
- Treat this error as 'instance gone' and tear down the polling loop.
When it happens
Trigger: Calling ffiGetScanProgress on a handle whose native instance no longer exists (already destroyed/invalid), or a native failure to allocate the progress struct while still reporting success.
Common situations: Polling scan progress from a timer after the finder was closed; polling before init completed with a stale handle; version-mismatched native binary.
Related errors
- FFI returned null pointer
- fff_search_mixed returned null search result
- grep returned null result
- 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/1f6fe10beb10fc20.
Report an issue: GitHub.
Appendix: source
Thrown at packages/fff-bun/src/ffi.ts:1352
}
// FffScanProgress { scanned_files_count: u64(8), is_scanning: bool(1), is_watcher_ready: bool(1), is_warmup_complete: bool(1) + pad }
const SP_COUNT = 0; // u64 (8)
const SP_SCANNING = 8; // bool (1)
const SP_WATCHER_READY = 9; // bool (1)
const SP_WARMUP_COMPLETE = 10; // bool (1)
/**
* Get scan progress.
*/
export function ffiGetScanProgress(handle: NativeHandle): Result<ScanProgress> {
const library = loadLibrary();
const resultPtr = library.symbols.fff_get_scan_progress(handle);
const envelope = readResultEnvelope(resultPtr);
if (!("success" in envelope)) return envelope;
if (envelope.handlePtr === 0) {
return err("scan progress returned null");
}
const hp = asPtr(envelope.handlePtr);
const result: ScanProgress = {
scannedFilesCount: Number(read.u64(hp, SP_COUNT)),
isScanning: read.u8(hp, SP_SCANNING) !== 0,
isWatcherReady: read.u8(hp, SP_WATCHER_READY) !== 0,
isWarmupComplete: read.u8(hp, SP_WARMUP_COMPLETE) !== 0,
};
library.symbols.fff_free_scan_progress(hp);
return { ok: true, value: result };
}
/**
* Wait for scan to complete.
*/
export function ffiWaitForScan(handle: NativeHandle, timeoutMs: number): Result<boolean> {
const library = loadLibrary();View on GitHub (pinned to 7f8537e70f)