dmtrKovalenko/fff · error

Query is null or invalid UTF-8

Error message

Query is null or invalid UTF-8

What it means

fff_search validates its query argument with cstr_to_str, which returns None when the pointer is NULL or the bytes are not valid UTF-8. The library refuses to search with an unusable query string and returns an error FffResult instead of panicking across the FFI boundary.

Solutions

  1. Ensure the query is a valid, NUL-terminated, UTF-8 encoded C string before calling.
  2. Check for NULL before invoking; skip the search if the query is absent.
  3. If input may be non-UTF-8, sanitize with String::from_utf8_lossy or equivalent before passing it.
  4. Verify the caller's string lifetime — the buffer must stay valid for the duration of the call.

Example fix

// before: possibly-uninitialized buffer
const char *query = NULL;
fff_search(inst, query, ...); // error
// after: guarantee a valid UTF-8 C string
const char *query = user_query ? user_query : "";
fff_search(inst, query, ...);
Defensive patterns

Strategy: validation

Validate before calling

if query == nil or not query:match('^[%w%p%s%z]*$') and #query == 0 then return end
assert(type(query) == 'string')

Type guard

local function is_valid_query(q) return type(q) == 'string' and #q > 0 end

Try / catch

local res = fff.search(inst, query or '')
if res.is_err then log('search rejected: invalid query') end

Prevention

When it happens

Trigger: Calling fff_search with query = NULL, a pointer to an empty/uninitialized buffer, a non-NUL-terminated C string, or bytes encoded in a non-UTF-8 locale (e.g. Latin-1 file names).

Common situations: Lua/C callers passing an uninitialized string buffer; passing strings containing invalid byte sequences from non-UTF-8 filenames; forgetting to NUL-terminate a manually built C string; passing nil/NULL because an earlier call failed and the query variable was never set.

Understand the failure class

Related errors


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

Appendix: source

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

#[unsafe(no_mangle)]
pub unsafe extern "C" fn fff_search(
    fff_handle: *mut c_void,
    query: *const c_char,
    current_file: *const c_char,
    max_threads: u32,
    page_index: u32,
    page_size: u32,
    combo_boost_multiplier: i32,
    min_combo_count: u32,
) -> *mut FffResult {
    let inst = match unsafe { instance_ref(fff_handle) } {
        Ok(i) => i,
        Err(e) => return e,
    };

    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.");
        }
    };

View on GitHub (pinned to 7f8537e70f)