run-llama/liteparse · critical

pdfium not loaded — call…

Error message

pdfium not loaded — call pdfium_sys::dynamic::load_default() first

What it means

`pdfium_sys::dynamic::pdfium()` returns the process-global handle to the dynamically loaded PDFium library, stored in a `OnceLock`-style static. It panics via `expect` when that static was never populated, i.e. neither `load()` nor `load_default()` completed successfully before any FFI call. It is an initialization-order bug: the library was used before the shared library was loaded.

Solutions

  1. Call `pdfium_sys::dynamic::load_default()?` at process start and propagate/inspect the error before any PDFium usage.
  2. Or call `pdfium_sys::dynamic::load(Path::new("/path/to/libpdfium.so"))` with an explicit library path before using the bindings.
  3. If using the higher-level liteparse-pdfium crate, call `Library::try_init()`/`Library::init()` first — it performs load_default() for you.
  4. Ensure the PDFIUM_LIB_PATH env var points to the directory containing the shared library so load_default() succeeds.

Example fix

// before
let bindings = pdfium_sys::dynamic::pdfium();
// after
pdfium_sys::dynamic::load_default().expect("pdfium shared library must be available");
let bindings = pdfium_sys::dynamic::pdfium();
Defensive patterns

Strategy: try-catch

Validate before calling

// call before any pdfium usage
fn ensure_pdfium_loaded() -> Result<(), String> {
    pdfium_sys::dynamic::load_default()
}

Type guard

// statics have no type guard; gate usage on an init flag
static LOADED: OnceLock<()> = OnceLock::new();
fn pdfium_ready() -> bool { LOADED.get().is_some() }

Try / catch

// catch_unwind around panic-based FFI access
let r = std::panic::catch_unwind(|| {
    let _ = pdfium_sys::dynamic::pdfium();
});
if r.is_err() { pdfium_sys::dynamic::load_default().unwrap(); }

Prevention

When it happens

Trigger: Calling any code path that reaches `dynamic::pdfium()` (direct FFI calls through the dynamic bindings) without first invoking `pdfium_sys::dynamic::load(path)` or `pdfium_sys::dynamic::load_default()` — or after a `load_default()` whose Err was ignored/unwrapped incorrectly.

Common situations: Calling low-level pdfium-sys APIs directly in tests or binaries without the init step that higher layers (like `Library::init`) normally perform; swallowing the Err from `load_default()` and continuing; running on a machine where loading silently failed earlier in the process lifetime.

Related errors


AI-assisted analysis of run-llama/liteparse@22d2dd8cd7 (2026-09-08). Data as JSON: /api/errors/c1e15be90e0a4326. Report an issue: GitHub.

Appendix: source

Thrown at crates/pdfium-sys/src/dynamic.rs:966

            }
        }
    }

    Err(format!(
        "could not find pdfium shared library. Last error: {last_err}. \
         Set PDFIUM_LIB_PATH to the directory containing {}",
        dylib_name()
    ))
}

/// Get a reference to the loaded pdfium bindings.
///
/// # Panics
/// Panics if `load()` or `load_default()` has not been called successfully.
pub fn pdfium() -> &'static PdfiumBindings {
    BINDINGS
        .get()
        .expect("pdfium not loaded — call pdfium_sys::dynamic::load_default() first")
}

View on GitHub (pinned to 22d2dd8cd7)