Stirling-Tools/Stirling-PDF · error · Error

Failed to parse PDF JSON document

Error message

Failed to parse PDF JSON document

What it means

Thrown as the final defensive guard after both the async and synchronous conversion paths. If parsed is still null/undefined after all code paths (async polling, synchronous JSON parsing), this fires. It indicates neither path successfully produced a PdfJsonDocument, which should be logically impossible if the code above executed correctly.

Source

Thrown at frontend/editor/src/core/tools/pdfTextEditor/PdfTextEditor.tsx:854

        } else {
          const content = await file.text();
          const docResult = JSON.parse(content) as PdfJsonDocument;
          parsed = {
            ...docResult,
            pages: docResult.pages ?? [],
          };
          shouldUseLazyMode = false;
          pendingJobId = null;
        }

        setConversionProgress(null);

        if (loadRequestIdRef.current !== requestId) {
          return;
        }

        if (!parsed) {
          throw new Error("Failed to parse PDF JSON document");
        }

        console.log(
          `[PdfTextEditor] Document loaded. Lazy image mode: ${shouldUseLazyMode}, Pages: ${parsed.pages?.length || 0}`,
        );

        if (isPdf) {
          initializePdfPreview(file);
        } else {
          clearPdfPreview();
        }

        setLoadedDocument(parsed);
        resetToDocument(parsed, groupingMode);
        setIsLazyMode(shouldUseLazyMode);
        const newJobId = shouldUseLazyMode ? pendingJobId : null;
        setCachedJobId(newJobId);
        cachedJobIdRef.current = newJobId;

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Add detailed logging of all local variables (isPdf, requestId match, parsed value) before this throw.
  2. Validate the input file is non-empty and is either a valid PDF or valid JSON before entering the conversion flow.
  3. If reproducible, report as a bug — this guard should be unreachable in normal operation.
  4. Check that loadRequestIdRef.current === requestId hasn't changed (stale request) before reaching this point.

Example fix

// before
if (!parsed) {
  throw new Error("Failed to parse PDF JSON document");
}

// after
if (!parsed) {
  console.error("Parse failed. isPdf:", isPdf, "requestId match:", loadRequestIdRef.current === requestId);
  throw new Error(
    isPdf
      ? "Failed to convert PDF. The file may be corrupted or unsupported."
      : "Failed to parse JSON document. The file may not be a valid PDF text editor file."
  );
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate input file before conversion
if (!file || file.size === 0) {
  throw new Error('Cannot convert an empty file.');
}
const isPdf = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
if (!isPdf && !file.name.toLowerCase().endsWith('.json')) {
  throw new Error('File must be a PDF or a PDF text editor JSON file.');
}

Type guard

function isParsedDocument(value: unknown): value is PdfJsonDocument {
  return value !== null && value !== undefined && typeof value === 'object' &&
    Array.isArray((value as any).pages);
}

Try / catch

try {
  // ... all conversion logic ...
} catch (error) {
  if (error instanceof Error && error.message === 'Failed to parse PDF JSON document') {
    setErrorMessage('The document could not be parsed. It may be corrupted or in an unsupported format.');
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: A code path that should set parsed was skipped due to an early return or conditional. The loadRequestIdRef check returned early but then fell through. An empty file (zero bytes) was passed, causing file.text() to return an empty string that JSON.parse handled unexpectedly.

Common situations: Empty or invalid file input. Logic regression after refactoring the conversion flow. Unhandled edge case where isPdf is false but the file is also not valid JSON.

Understand the failure class

Related errors


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