dmtrKovalenko/fff · error
Unsupported FffCreateOptions version
Error message
Unsupported FffCreateOptions version {} (library understands up to {}) What it means
The FffCreateOptions struct is versioned for ABI stability. If opts.version is 0 (uninitialized struct) or greater than FFF_CREATE_OPTIONS_VERSION (built against a newer header than the loaded library), creation is refused. This prevents misinterpreting a struct layout the library does not understand.
Solutions
- Set opts.version = FFF_CREATE_OPTIONS_VERSION from the header you compile against.
- Rebuild/reinstall the native library so it matches the bindings' expected version.
- Ensure only one version of the fff shared library is on the library path (check with ldd / LD_LIBRARY_PATH).
- Zero-initialized structs must explicitly set the version field.
Example fix
// before
FffCreateOptions opts = {0}; // version left at 0
// after
FffCreateOptions opts = {0};
opts.version = FFF_CREATE_OPTIONS_VERSION;
opts.base_path = "/repo"; Defensive patterns
Strategy: validation
Validate before calling
if (!opts.version || opts.version > FFF_CREATE_OPTIONS_VERSION) throw new Error(`unsupported FffCreateOptions version ${opts.version}`); Type guard
function hasSupportedVersion(o) { return Number.isInteger(o.version) && o.version >= 1 && o.version <= FFF_CREATE_OPTIONS_VERSION; } Try / catch
const res = fff_create_instance_with(opts);
if (!res.ok && /Unsupported FffCreateOptions version/.test(res.error)) {
reloadNativeLibrary(); // rebuild/reinstall to match versions
retry();
} Prevention
- Always set version = FFF_CREATE_OPTIONS_VERSION from the compiled header.
- Keep bindings and native library versions in lockstep.
- Never hand zero structs without setting version.
- After upgrades, confirm the loaded .so/.dll is the new build.
When it happens
Trigger: Passing a zero-initialized FffCreateOptions without setting version; loading an older shared library with options built from a newer fff-c header (version > FFF_CREATE_OPTIONS_VERSION).
Common situations: Upgrading the npm/package bindings without reloading/rebuilding the native library (stale .so/.dll on disk); memset(0) structs where version was forgotten; mixing headers from different versions in one build.
Related errors
- Instance handle is null. Create one with…
- opts is null
- opts.base_path is null or empty
- Failed to init tracing
- Failed to acquire frecency lock
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/b8d1ebed1746f473.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fff-c/src/lib.rs:189
/// pointer. New fields are only appended; older `version` values keep working.
/// FFI bindings needing struct-by-value should use [`fff_create_instance_with_value`].
///
/// `opts.base_path` is required (non-NULL, non-empty). Zero `cache_budget_*`
/// values are auto-computed from repo size after the initial scan.
///
/// ## Safety
/// * `opts` must be a valid pointer to an `FffCreateOptions` whose `version`
/// 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());View on GitHub (pinned to 7f8537e70f)