Stirling-Tools/Stirling-PDF · error · Error

Parent stub not found

Error message

Parent stub not found

What it means

Thrown in EmbedPdfViewer's export path when selectors.getStirlingFileStub(currentFileId) returns null. The stub is the FileContext's metadata record (parent version, operation history) for the file. Without it, createStirlingFilesAndStubs() cannot establish parent-child version lineage for the exported copy.

Source

Thrown at frontend/editor/src/core/components/viewer/EmbedPdfViewer.tsx:643

      // Step 1: Export PDF with annotations using EmbedPDF
      const arrayBuffer = await exportActions.saveAsCopy();
      if (!arrayBuffer) {
        throw new Error("Failed to export PDF");
      }

      // Step 2: Convert ArrayBuffer to File
      const blob = new Blob([arrayBuffer], { type: "application/pdf" });
      const filename = currentFile.name || "document.pdf";
      const file = new File([blob], filename, { type: "application/pdf" });

      // Step 3: Create StirlingFiles and stubs for version history
      // Only consume the current file, not all active files
      const currentFileId = currentFileStableId;
      if (!currentFileId) throw new Error("Current file ID not found");

      const parentStub = selectors.getStirlingFileStub(currentFileId);
      if (!parentStub) throw new Error("Parent stub not found");

      const { stirlingFiles, stubs } = await createStirlingFilesAndStubs(
        [file],
        parentStub,
        selectedTool ?? "multiTool",
      );

      // Store the page to restore after file replacement triggers re-render
      pendingScrollRestoreRef.current = pageToRestore;
      scrollRestoreAttemptsRef.current = 0;

      // Store the rotation to restore after file replacement
      pendingRotationRestoreRef.current = currentRotation;
      rotationRestoreAttemptsRef.current = 0;
      // Track the new file ID so the viewer follows it after the list reorders
      const newFileId = stubs[0]?.id;
      if (newFileId) setActiveFileId(newFileId);

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Verify the stub exists before starting the export: const stub = selectors.getStirlingFileStub(currentFileId); if (!stub) { /* recreate or abort */ }.
  2. If the stub is missing, create a fresh one via createStirlingFileStub before proceeding with the export.
  3. Add a selector that checks stub existence reactively and disables export when false.
  4. Log the currentFileId and list of known stub IDs when this hits to diagnose eviction vs mismatch.

Example fix

// before
const parentStub = selectors.getStirlingFileStub(currentFileId);
if (!parentStub) throw new Error("Parent stub not found");

// after
const parentStub = selectors.getStirlingFileStub(currentFileId);
if (!parentStub) {
  console.error("Stub not found for file", currentFileId, "known stubs:", Object.keys(stateRef.current.files.byId));
  setErrorMessage("File metadata is missing. Reloading the file may fix this.");
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

// Verify stub exists before starting the export workflow
const stub = selectors.getStirlingFileStub(currentFileId);
if (!stub) {
  console.error('No stub for file', currentFileId, '. Known:', Object.keys(stateRef.current.files.byId));
  setErrorMessage('File metadata is missing. Please reload the file.');
  return;
}

Type guard

function hasFileStub(selectors: FileContextSelectors, fileId: string): boolean {
  const stub = selectors.getStirlingFileStub(fileId);
  return stub !== null && stub !== undefined && typeof stub.id === 'string';
}

Prevention

When it happens

Trigger: The file's stub was evicted from in-memory state (FileContext reducer), the stub was never created for this file (e.g., file loaded via a non-standard path), or the currentFileId doesn't match any stub due to ID mismatch.

Common situations: IndexedDB cache eviction under memory pressure removed the stub. File was loaded via drag-and-drop or external route that bypassed stub creation. A previous consumeFiles operation removed the stub while the viewer still held the file.

Related errors


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