dmtrKovalenko/fff · error

File picker not initialized. Call fff_create_instance first.

Error message

File picker not initialized. Call fff_create_instance first.

What it means

fff_search acquires the picker lock and then unwraps the Option<FilePicker>; if the slot is None the instance exists but its picker was never initialized (or was torn down). The library returns this error telling the caller to create an instance first.

Solutions

  1. Call fff_create_instance (or _with) and confirm it returned a success result before searching.
  2. If the instance was destroyed, obtain a fresh instance handle instead of reusing the old pointer.
  3. Check initialization order in the host app: create instance → wait for success → search.
  4. Enable logging around instance creation to confirm the picker actually initialized.

Example fix

// before
fff_search(inst, "query", ...); // inst may be uninitialized
// after
let inst = fff_create_instance(c"/project");
if inst.is_ok() { fff_search(inst, "query", ...); }
Defensive patterns

Strategy: type-guard

Validate before calling

assert(inst ~= nil and inst ~= ffi.NULL, 'instance must be created before search')

Type guard

local function has_instance(h) return h ~= nil and h ~= ffi.NULL end

Try / catch

if not has_instance(inst) then
  inst = fff.create_instance(vim.fn.getcwd())
end
local res = fff.search(inst, q)

Prevention

When it happens

Trigger: Calling fff_search with a valid FffInstance whose picker slot is None — e.g. an instance created through a path that skipped picker init, or after the picker was cleared/destroyed while the instance handle was still used.

Common situations: Using a stale instance handle after library shutdown or re-initialization; a previous fff_create_instance failure left a half-built instance; ordering bug where search is called before instance creation completes in async setup code.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at crates/fff-c/src/lib.rs:369

    let query_str = match unsafe { cstr_to_str(query) } {
        Some(s) => s,
        None => return FffResult::err("Query is null or invalid UTF-8"),
    };

    let current_file_str = unsafe { optional_cstr(current_file) };
    let page_size = default_u32(page_size, 100) as usize;
    let min_combo_count = default_u32(min_combo_count, 3);
    let combo_boost_multiplier = default_i32(combo_boost_multiplier, 100);

    let picker_guard = match inst.picker.read() {
        Ok(g) => g,
        Err(e) => return FffResult::err(&format!("Failed to acquire file picker lock: {}", e)),
    };

    let picker = match picker_guard.as_ref() {
        Some(p) => p,
        None => {
            return FffResult::err("File picker not initialized. Call fff_create_instance first.");
        }
    };

    // Get query tracker ref for combo matching
    let qt_guard = match inst.query_tracker.read() {
        Ok(q) => q,
        Err(_) => return FffResult::err("Failed to acquire query tracker lock"),
    };
    let query_tracker_ref = qt_guard.as_ref();

    let parser = QueryParser::default();
    let parsed = parser.parse(query_str);

    let results = picker.fuzzy_search(
        &parsed,
        query_tracker_ref,
        FuzzySearchOptions {
            max_threads: max_threads as usize,

View on GitHub (pinned to 7f8537e70f)