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
- Verify the stub exists before starting the export: const stub = selectors.getStirlingFileStub(currentFileId); if (!stub) { /* recreate or abort */ }.
- If the stub is missing, create a fresh one via createStirlingFileStub before proceeding with the export.
- Add a selector that checks stub existence reactively and disables export when false.
- 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
- Check stub existence before entering any async export workflow.
- Log known stub IDs alongside the missing ID to distinguish eviction from mismatch.
- Avoid file removal operations while export is in progress.
- Consider pinning stubs in state while a file is actively being viewed/edited.
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
- Current file ID not found
- The selected file is no longer available.
- Failed to export PDF
- Failed to build payload
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/6323fe94b9847891.
Report an issue: GitHub.