Stirling-Tools/Stirling-PDF · error · Error

Current file ID not found

Error message

Current file ID not found

What it means

Thrown in EmbedPdfViewer's export path (handleSaveAsCopy) when currentFileStableId is null/undefined. This stableId is the FileContext identifier used to look up the file's stub for version history. Without it, the code cannot create child stubs linking the exported PDF to its parent.

Source

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

        // Give a small delay for the commit to process
        await new Promise((resolve) => setTimeout(resolve, 100));
      }

      // 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

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Capture currentFileStableId at the start of the export function into a local const, not read it mid-async.
  2. Disable file switching (tool navigation, file removal) while an export is in progress.
  3. Guard the export button with a check that currentFileStableId is truthy before allowing the click.
  4. Use an AbortController to cancel the export if the active file changes.

Example fix

// before
const currentFileId = currentFileStableId;
if (!currentFileId) throw new Error("Current file ID not found");

// after
const currentFileId = currentFileStableId;
if (!currentFileId) {
  setErrorMessage("Cannot export: no active file. Please select a file and try again.");
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

// Capture the file ID synchronously at function entry, before any awaits
const fileId = currentFileStableId;
if (!fileId) {
  setErrorMessage('No active file to export. Please select a file first.');
  return;
}
// Use fileId throughout — never re-read currentFileStableId after awaits

Type guard

function hasStableId(value: string | null | undefined): value is string {
  return typeof value === 'string' && value.length > 0;
}

Prevention

When it happens

Trigger: The active file in FileContext doesn't have a stableId assigned, or the file was navigated away from (switched/closed) during the async export operation, leaving currentFileStableId stale or null.

Common situations: File loaded from IndexedDB before stableId assignment completed. User switched to another file while the export was mid-flight. The file was consumed/removed by another tool operation before this export finished.

Related errors


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