{"record":{"id":"35e4c5a2574fb3cf","repo":"dmtrKovalenko/fff","slug":"opts-base-path-is-null-or-empty","errorCode":null,"errorMessage":"opts.base_path is null or empty","messagePattern":"opts\\.base_path is null or empty","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fff-c/src/lib.rs","lineNumber":197,"sourceCode":"///   is in the range `1..=FFF_CREATE_OPTIONS_VERSION`.\n/// * All string pointers inside `opts` must be valid null-terminated UTF-8\n///   or NULL.\n#[unsafe(no_mangle)]\npub unsafe extern \"C\" fn fff_create_instance_with(opts: *const FffCreateOptions) -> *mut FffResult {\n    if opts.is_null() {\n        return FffResult::err(\"opts is null\");\n    }\n    let opts = unsafe { &*opts };\n    if opts.version == 0 || opts.version > FFF_CREATE_OPTIONS_VERSION {\n        return FffResult::err(&format!(\n            \"Unsupported FffCreateOptions version {} (library understands up to {})\",\n            opts.version, FFF_CREATE_OPTIONS_VERSION\n        ));\n    }\n\n    let base_path_str = match unsafe { cstr_to_str(opts.base_path) } {\n        Some(s) if !s.is_empty() => s.to_string(),\n        _ => return FffResult::err(\"opts.base_path is null or empty\"),\n    };\n\n    if let Some(log_path) = unsafe { optional_cstr(opts.log_file_path) } {\n        let level = unsafe { optional_cstr(opts.log_level) };\n        if let Err(e) = fff::log::init_tracing(log_path, level, None) {\n            return FffResult::err(&format!(\"Failed to init tracing: {}\", e));\n        }\n    }\n\n    let frecency_path = unsafe { optional_cstr(opts.frecency_db_path) }.map(|s| s.to_string());\n    let history_path = unsafe { optional_cstr(opts.history_db_path) }.map(|s| s.to_string());\n\n    let shared_picker = SharedFilePicker::default();\n    let shared_frecency = SharedFrecency::default();\n    let query_tracker = SharedQueryTracker::default();\n\n    if let Some(ref frecency_path) = frecency_path {\n        if let Some(parent) = PathBuf::from(frecency_path).parent() {","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/crates/fff-c/src/lib.rs#L179-L215","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","solutions":["Set opts.base_path to a non-empty, absolute path to the workspace root.","If you want the current directory, resolve and pass cwd explicitly (e.g. getcwd()).","In bindings, default the option to process cwd when unset instead of passing null/empty.","Validate the base_path value at the binding layer before invoking the FFI call."],"exampleFix":"// before\nopts.base_path = \"\";\n// after\nopts.base_path = \"/home/me/project\"; // or resolved cwd","handlingStrategy":"validation","validationCode":"if (typeof basePath !== 'string' || basePath.trim() === '') throw new Error('fff: base_path is required and must be non-empty');","typeGuard":"function hasBasePath(o) { return typeof o?.base_path === 'string' && o.base_path.trim().length > 0; }","tryCatchPattern":"const base = cfg.workspace || process.cwd();\nif (!hasBasePath({ base_path: base })) throw new Error('workspace root required');\nopts.base_path = base;","preventionTips":["Default base_path to process.cwd() when unset.","Validate config before instantiating the picker.","Never pass empty strings for required FFI string fields.","Document base_path as required in binding options."],"tags":["ffi","rust","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"7f8537e70f0ea1210f9acbbfc4640141105cdc78","analyzedAt":"2026-09-10T07:26:53.407Z","contentChangedAt":"2026-09-10T07:26:53.407Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}