Stirling-Tools/Stirling-PDF · error · Error

Failed to process ${file.name}: ${error instanceof Error ? e

Error message

Failed to process ${file.name}: ${error instanceof Error ? error.message : "Unknown error"}

What it means

The outer catch-all in removeAnnotationsProcessor. It wraps any error thrown while opening the PDF with PDFium, removing annotations, or saving — rethrowing with the offending filename and the original error as `cause`. The inner message is whatever the PDFium/WASM layer produced (allocation failure, corrupt PDF, save error).

Source

Thrown at frontend/editor/src/core/hooks/tools/removeAnnotations/useRemoveAnnotationsOperation.ts:65

                err,
              );
            }
          }

          m.FPDF_ClosePage(pagePtr);
        }

        const outBytes = await saveRawDocument(docPtr);
        const processedFile = new File([outBytes], file.name, {
          type: "application/pdf",
        });
        processedFiles.push(processedFile);
      } finally {
        closeDocAndFreeBuffer(m, docPtr);
      }
    } catch (error) {
      console.error("Error processing file:", file.name, error);
      throw new Error(
        `Failed to process ${file.name}: ${error instanceof Error ? error.message : "Unknown error"}`,
        {
          cause: error,
        },
      );
    }
  }

  return {
    files: processedFiles,
    consumedAllInputs: false,
  };
};

// Static configuration object
export const removeAnnotationsOperationConfig = defineCustomTool({
  operationType: "removeAnnotations",
  customProcessor: removeAnnotationsProcessor,

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Read `error.cause` to find the underlying PDFium failure and address that specifically (memory, encryption, corruption).
  2. Validate the file is a readable, unencrypted PDF before entering the PDFium pipeline (check %PDF magic, attempt a probe open).
  3. Handle encrypted PDFs explicitly with a user-facing 'This PDF is password-protected' message.
  4. Cap input size and page count to avoid WASM exhaustion during save.

Example fix

// before
throw new Error(`Failed to process ${file.name}: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error });

// after — classify known causes for clearer UX
const reason = /encrypt|password/i.test(String(error))
  ? "PDF is password-protected"
  : error instanceof Error ? error.message : "Unknown error";
throw new Error(`Failed to process ${file.name}: ${reason}`, { cause: error });
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the file is a readable, unencrypted PDF before PDFium processing
const head = new Uint8Array(await file.slice(0, 5).arrayBuffer());
const isPdfMagic = String.fromCharCode(...head) === "%PDF-";
if (!isPdfMagic) {
  // reject up front with a clear 'not a PDF' message
}

Try / catch

try {
  await removeAnnotationsProcessor(params, files);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Failed to process ") && e.cause) {
    const cause = e.cause instanceof Error ? e.cause.message : String(e.cause);
    if (/encrypt|password/i.test(cause)) toast.error("This PDF is password-protected.");
    else throw e;
  } else throw e;
}

Prevention

When it happens

Trigger: openRawDocumentSafe fails on a corrupt or encrypted PDF; FPDF_LoadPage returns null and a downstream call dereferences it; saveRawDocument fails (WASM memory); the source file is not actually a PDF despite its extension.

Common situations: User drops an encrypted/password-protected PDF; a malformed PDF that PDFium rejects; very large PDF exhausting WASM memory during save; file got renamed to .pdf but is another format.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/cdb684d7d4d218ec. Report an issue: GitHub.