{"record":{"id":"5d72f5ac1b9a415c","repo":"firecrawl/pdf-inspector","slug":"context-error","errorCode":null,"errorMessage":"{context}: {error}","messagePattern":"\\{context\\}: \\{error\\}","errorType":"exception","errorClass":"js_sys::Error (JsValue)","httpStatus":null,"severity":"error","filePath":"wasm/src/lib.rs","lineNumber":175,"sourceCode":"#[serde(rename_all = \"camelCase\")]\nstruct WasmPdfClassification {\n    pdf_type: &'static str,\n    page_count: u32,\n    pages_needing_ocr: Vec<u32>,\n    confidence: f64,\n}\n\nfn pdf_type_name(pdf_type: PdfType) -> &'static str {\n    match pdf_type {\n        PdfType::TextBased => \"TextBased\",\n        PdfType::Scanned => \"Scanned\",\n        PdfType::ImageBased => \"ImageBased\",\n        PdfType::Mixed => \"Mixed\",\n    }\n}\n\nfn js_error(context: &str, error: impl std::fmt::Display) -> JsValue {\n    js_sys::Error::new(&format!(\"{context}: {error}\")).into()\n}\n\nfn deserialize_options(value: JsValue) -> Result<WasmProcessOptions, JsValue> {\n    if value.is_undefined() || value.is_null() {\n        return Ok(WasmProcessOptions::default());\n    }\n\n    serde_wasm_bindgen::from_value(value).map_err(|error| js_error(\"invalid options\", error))\n}\n\nfn build_options(value: JsValue, mode: ProcessMode) -> Result<PdfOptions, JsValue> {\n    let options = deserialize_options(value)?;\n    if options\n        .pages\n        .as_ref()\n        .is_some_and(|pages| pages.contains(&0))\n    {\n        return Err(js_error(","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/firecrawl/pdf-inspector/blob/636ca1a58bdc1af4cd3fc20b8c1f549a1121cca7/wasm/src/lib.rs#L157-L193","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst result = await wasm.processPdf(buffer, { maxPages: 'all' });\n// after\nconst opts = { maxPages: Number.isFinite(limit) ? limit : undefined };\nif (!buffer?.byteLength || new TextDecoder().decode(buffer.slice(0,5)) !== '%PDF-') throw new Error('not a PDF');\nconst result = await wasm.processPdf(buffer, opts);","handlingStrategy":"validation","validationCode":"function validateWasmInput(buffer, options) {\n  if (!(buffer instanceof Uint8Array) || buffer.byteLength === 0) throw new TypeError('expected non-empty Uint8Array of PDF bytes');\n  const head = new TextDecoder('latin1').decode(buffer.subarray(0, 5));\n  if (!head.startsWith('%PDF-')) throw new TypeError('not a PDF');\n  const allowed = new Set(['maxPages', 'tables', 'ocr']); // documented keys\n  if (options != null && Object.keys(options).some(k => !allowed.has(k))) throw new TypeError('unknown option key');\n}","typeGuard":"function isJsErrorValue(v) {\n  return typeof JsError !== 'undefined'\n    ? v instanceof JsError\n    : v instanceof Error && typeof v.message === 'string';\n}","tryCatchPattern":"try {\n  const result = await wasm.processPdf(buffer, options);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  const [context, cause] = msg.split(/: (.+)/);\n  if (context === 'deserialize_options') throw new TypeError('bad options: ' + cause);\n  throw e;\n}","preventionTips":["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."],"tags":["wasm","javascript","options-validation","error-wrapping"],"backgroundTag":"wasm-binding-error","analyzedSha":"636ca1a58bdc1af4cd3fc20b8c1f549a1121cca7","analyzedAt":"2026-09-05T08:40:31.256Z","contentChangedAt":"2026-09-05T08:40:31.256Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}