Stirling-Tools/Stirling-PDF · error · Error
Missing file data for ${stub.name || stub.id}
Error message
Missing file data for ${stub.name || stub.id} What it means
A stub (metadata) exists but `getStirlingFile(stub.id)` returns null — the actual file bytes are gone. `getStirlingFile` returns null when the IndexedDB record is missing, OR when the record is in the session's `unreadableRecords` set (a prior read of a lost WebKit blob-backing-store was detected and the id is short-circuited). So the metadata survived but the blob did not.
Source
Thrown at frontend/editor/src/core/services/serverStorageBundle.ts:65
stubs: Awaited<ReturnType<typeof fileStorage.getHistoryChainStubs>>;
}> = [];
for (const rootId of uniqueRoots) {
const stubs = await fileStorage.getHistoryChainStubs(rootId);
if (stubs.length === 0) {
throw new Error("No history chain found for file.");
}
allStubs.push({ rootId, stubs });
}
const zip = new JSZip();
const entries: ShareBundleEntry[] = [];
for (const chain of allStubs) {
for (const stub of chain.stubs) {
const file = await fileStorage.getStirlingFile(stub.id);
if (!file) {
throw new Error(`Missing file data for ${stub.name || stub.id}`);
}
const logicalId = stub.id;
const filePath = `files/${logicalId}/${sanitizeFilename(stub.name || "file")}`;
const buffer = await file.arrayBuffer();
zip.file(filePath, buffer);
entries.push({
logicalId,
rootLogicalId: chain.rootId,
parentLogicalId: stub.parentFileId,
versionNumber: stub.versionNumber || 1,
name: stub.name,
type: stub.type,
size: stub.size,
lastModified: stub.lastModified,
toolHistory: stub.toolHistory,
filePath,View on GitHub (pinned to 9ef20dcab8)
Solutions
- Before bundling, pre-check `getStirlingFileStub(id).dataUnavailable` (the stub exposes this flag) and exclude/skip unreadable files with a warning instead of aborting the whole bundle.
- Offer the user a re-upload flow for the missing file(s).
- For Safari, periodically re-hydrate critical blobs (re-write them) to defend against backing-store loss.
- Telemetry: log which ids are missing so eviction patterns are visible.
Example fix
// before
const file = await fileStorage.getStirlingFile(stub.id);
if (!file) {
throw new Error(`Missing file data for ${stub.name || stub.id}`);
}
// after (skip missing, continue bundling the rest)
const file = await fileStorage.getStirlingFile(stub.id);
if (!file) {
missing.push(stub);
continue;
}
// after the loop:
if (missing.length) console.warn('Skipped missing files:', missing.map(s => s.name));
if (entries.length === 0) throw new Error('All selected files are unavailable.'); Defensive patterns
Strategy: validation
Validate before calling
// Skip files whose data is flagged unavailable before bundling
const stub = await fileStorage.getStirlingFileStub(stubId);
if (stub?.dataUnavailable) {
console.warn(`Skipping unreadable file ${stub.name}`);
continue;
} Type guard
function hasFileData(file: StirlingFile | null): file is StirlingFile {
return file !== null && file.size > 0;
} Try / catch
try {
await buildHistoryBundle(rootId);
} catch (e) {
if (e instanceof Error && e.message.startsWith("Missing file data for")) {
notifyUser("Some files in this history are no longer available. Re-upload them to share.");
} else throw e;
} Prevention
- Pre-check stub.dataUnavailable and exclude flagged files before bundling.
- Skip missing files and continue bundling the rest rather than aborting the whole bundle.
- On Safari, periodically re-hydrate critical blobs to defend against backing-store loss.
- Offer a re-upload flow for files whose bytes were evicted.
When it happens
Trigger: WebKit/Safari lost the blob's backing-store data (a known IndexedDB blob bug); the user cleared site data partially; the blob was evicted by an LRU/size policy; the record was marked unreadable earlier in the session after a failed read. Also reachable from `buildSharePackage` at line 129 with the same cause.
Common situations: Safari blob-loss after the OS reclaimed disk space; restoring an old IndexedDB whose blobs were garbage-collected; sharing a file whose data was never persisted (memory-only); a prior `getStirlingFile` read failed and added the id to `unreadableRecords`.
Related errors
- No history chain found for file.
- Missing final file data for sharing.
- IndexedDB context not available
- Database not initialized
- No files provided for sharing.
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/dcf91d2caad93832.
Report an issue: GitHub.