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
- Read the context prefix to see which entry point failed; if it is deserialize_options/build_options, fix the options object shape and types.
- Validate inputs in JS before calling: instanceof check on Uint8Array, %PDF- magic bytes, only documented option keys.
- Await/catch the promise from the WASM call — this error is delivered as a rejected Promise or thrown JsValue.
- 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
- Type-check the options object against the generated .d.ts (or a zod/valibot schema) before calling WASM functions.
- Verify PDF magic bytes and non-empty buffers before invoking bindings.
- Always await and catch WASM calls — errors arrive as rejected Promises/JsValues.
- For PDFs that fail only in WASM, retry with the native build which supports a broader feature set.
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.