firecrawl/pdf-inspector · error · js_sys::Error (JsValue)

{context}: {error}

Error message

{context}: {error}

What it means

js_error in wasm/src/lib.rs converts any Rust-side error into a JavaScript JsValue (js_sys::Error) with message "{context}: {error}". It is used by deserialize_options, build_options, serialize, process_pdf, detect_pdf and classify_pdf, so every failure of the WASM API surfaces as a rejected Promise or thrown JS Error. The context prefix identifies which WASM entry point failed.

Source

Thrown at wasm/src/lib.rs:175

#[serde(rename_all = "camelCase")]
struct WasmPdfClassification {
    pdf_type: &'static str,
    page_count: u32,
    pages_needing_ocr: Vec<u32>,
    confidence: f64,
}

fn pdf_type_name(pdf_type: PdfType) -> &'static str {
    match pdf_type {
        PdfType::TextBased => "TextBased",
        PdfType::Scanned => "Scanned",
        PdfType::ImageBased => "ImageBased",
        PdfType::Mixed => "Mixed",
    }
}

fn js_error(context: &str, error: impl std::fmt::Display) -> JsValue {
    js_sys::Error::new(&format!("{context}: {error}")).into()
}

fn deserialize_options(value: JsValue) -> Result<WasmProcessOptions, JsValue> {
    if value.is_undefined() || value.is_null() {
        return Ok(WasmProcessOptions::default());
    }

    serde_wasm_bindgen::from_value(value).map_err(|error| js_error("invalid options", error))
}

fn build_options(value: JsValue, mode: ProcessMode) -> Result<PdfOptions, JsValue> {
    let options = deserialize_options(value)?;
    if options
        .pages
        .as_ref()
        .is_some_and(|pages| pages.contains(&0))
    {
        return Err(js_error(

View on GitHub (pinned to 636ca1a58b)

Solutions

  1. Read the context prefix to see which entry point failed; if it is deserialize_options/build_options, fix the options object shape and types.
  2. Validate inputs in JS before calling: instanceof check on Uint8Array, %PDF- magic bytes, only documented option keys.
  3. Await/catch the promise from the WASM call — this error is delivered as a rejected Promise or thrown JsValue.
  4. If the underlying error indicates a PDF parsing limitation, try the native (napi/CLI) build, which supports more features than WASM.

Example fix

// before
const result = await wasm.processPdf(buffer, { maxPages: 'all' });
// after
const opts = { maxPages: Number.isFinite(limit) ? limit : undefined };
if (!buffer?.byteLength || new TextDecoder().decode(buffer.slice(0,5)) !== '%PDF-') throw new Error('not a PDF');
const result = await wasm.processPdf(buffer, opts);
Defensive patterns

Strategy: validation

Validate before calling

function validateWasmInput(buffer, options) {
  if (!(buffer instanceof Uint8Array) || buffer.byteLength === 0) throw new TypeError('expected non-empty Uint8Array of PDF bytes');
  const head = new TextDecoder('latin1').decode(buffer.subarray(0, 5));
  if (!head.startsWith('%PDF-')) throw new TypeError('not a PDF');
  const allowed = new Set(['maxPages', 'tables', 'ocr']); // documented keys
  if (options != null && Object.keys(options).some(k => !allowed.has(k))) throw new TypeError('unknown option key');
}

Type guard

function isJsErrorValue(v) {
  return typeof JsError !== 'undefined'
    ? v instanceof JsError
    : v instanceof Error && typeof v.message === 'string';
}

Try / catch

try {
  const result = await wasm.processPdf(buffer, options);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  const [context, cause] = msg.split(/: (.+)/);
  if (context === 'deserialize_options') throw new TypeError('bad options: ' + cause);
  throw e;
}

Prevention

When it happens

Trigger: Calling process_pdf/detect_pdf/classify_pdf with a malformed options object (deserialize_options/build_options), invalid PDF bytes, or failing to serialize results; also thrown for any underlying pdf-inspector error inside WASM.

Common situations: Passing options with wrong types (e.g. string where number expected, unknown option key) to a WASM binding; feeding a non-PDF ArrayBuffer; calling from a non-browser/non-wasm-bindgen context where JsValue conversion fails; PDFs with features unsupported in the WASM build.

Related errors


AI-assisted analysis of firecrawl/pdf-inspector@636ca1a58b (2026-09-05). Data as JSON: /api/errors/5d72f5ac1b9a415c. Report an issue: GitHub.