dmtrKovalenko/fff · error

opts.base_path is null or empty

Error message

opts.base_path is null or empty

What it means

This sentinel validation error fires inside fff_create_instance_with when the FffCreateOptions.base_path field is a NULL pointer or an empty string, i.e. the caller asked to create a picker instance without telling the library which root directory to index. It is one of the argument-validation guards at the top of the function (alongside the null opts and unsupported-version checks), so it fires before any filesystem or index work begins and no instance is created. Callers hitting it are passing a struct whose base_path was never filled in or was zeroed/emptied by an earlier step.

Solutions

  1. Set opts.base_path to a non-empty, absolute path to the workspace root.
  2. If you want the current directory, resolve and pass cwd explicitly (e.g. getcwd()).
  3. In bindings, default the option to process cwd when unset instead of passing null/empty.
  4. Validate the base_path value at the binding layer before invoking the FFI call.

Example fix

// before
opts.base_path = "";
// after
opts.base_path = "/home/me/project"; // or resolved cwd
Defensive patterns

Strategy: validation

Validate before calling

if (typeof basePath !== 'string' || basePath.trim() === '') throw new Error('fff: base_path is required and must be non-empty');

Type guard

function hasBasePath(o) { return typeof o?.base_path === 'string' && o.base_path.trim().length > 0; }

Try / catch

const base = cfg.workspace || process.cwd();
if (!hasBasePath({ base_path: base })) throw new Error('workspace root required');
opts.base_path = base;

Prevention

When it happens

Trigger: Calling fff_create_instance_with with opts.base_path == NULL or pointing to an empty string ""; forgetting to fill base_path in a partially initialized options struct.

Common situations: Bindings that map an optional 'root' config option straight to base_path; a config file where the workspace path key is missing, producing an empty string; passing "" intending 'current directory'.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

///   is in the range `1..=FFF_CREATE_OPTIONS_VERSION`.
/// * All string pointers inside `opts` must be valid null-terminated UTF-8
///   or NULL.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn fff_create_instance_with(opts: *const FffCreateOptions) -> *mut FffResult {
    if opts.is_null() {
        return FffResult::err("opts is null");
    }
    let opts = unsafe { &*opts };
    if opts.version == 0 || opts.version > FFF_CREATE_OPTIONS_VERSION {
        return FffResult::err(&format!(
            "Unsupported FffCreateOptions version {} (library understands up to {})",
            opts.version, FFF_CREATE_OPTIONS_VERSION
        ));
    }

    let base_path_str = match unsafe { cstr_to_str(opts.base_path) } {
        Some(s) if !s.is_empty() => s.to_string(),
        _ => return FffResult::err("opts.base_path is null or empty"),
    };

    if let Some(log_path) = unsafe { optional_cstr(opts.log_file_path) } {
        let level = unsafe { optional_cstr(opts.log_level) };
        if let Err(e) = fff::log::init_tracing(log_path, level, None) {
            return FffResult::err(&format!("Failed to init tracing: {}", e));
        }
    }

    let frecency_path = unsafe { optional_cstr(opts.frecency_db_path) }.map(|s| s.to_string());
    let history_path = unsafe { optional_cstr(opts.history_db_path) }.map(|s| s.to_string());

    let shared_picker = SharedFilePicker::default();
    let shared_frecency = SharedFrecency::default();
    let query_tracker = SharedQueryTracker::default();

    if let Some(ref frecency_path) = frecency_path {
        if let Some(parent) = PathBuf::from(frecency_path).parent() {

View on GitHub (pinned to 7f8537e70f)