Stirling-Tools/Stirling-PDF · error · Error
No history chain found.
Error message
No history chain found.
What it means
Thrown by uploadHistoryChain when getHistoryChainStubs returns an empty array: no stored stub has originalFileId (or id) equal to the supplied originalFileId. The file has no recorded version history in IndexedDB.
Source
Thrown at frontend/editor/src/core/services/serverStorageUpload.ts:27
function resolveUpdatedAt(value: unknown): number {
if (!value) {
return Date.now();
}
if (typeof value === "number") {
return Number.isFinite(value) ? value : Date.now();
}
const parsed = new Date(String(value)).getTime();
return Number.isFinite(parsed) ? parsed : Date.now();
}
export async function uploadHistoryChain(
originalFileId: FileId,
existingRemoteId?: number,
): Promise<{ remoteId: number; updatedAt: number; chain: StirlingFileStub[] }> {
const chain = await fileStorage.getHistoryChainStubs(originalFileId);
if (chain.length === 0) {
throw new Error("No history chain found.");
}
const finalStub =
chain
.slice()
.reverse()
.find((stub) => stub.isLeaf !== false) || chain[chain.length - 1];
const finalFile = await fileStorage.getStirlingFile(finalStub.id);
if (!finalFile) {
throw new Error("Missing final file data for sharing.");
}
const { bundleFile, manifest } = await buildHistoryBundle(originalFileId);
const auditLog = new File(
[JSON.stringify(manifest, null, 2)],
"audit-log.json",
{
type: "application/json",View on GitHub (pinned to 9ef20dcab8)
Solutions
- Persist the file with fileStorage.storeStirlingFile before calling uploadHistoryChain.
- Verify the chain is non-empty via getHistoryChainStubs(originalFileId) before uploading.
- For standalone leaves with no history, route to a share path that does not require a chain.
Example fix
// before
const chain = await fileStorage.getHistoryChainStubs(originalFileId);
if (chain.length === 0) throw new Error('No history chain found.');
// after
const chain = await fileStorage.getHistoryChainStubs(originalFileId);
if (chain.length === 0) {
// ensure the file is stored and self-linked as its own root
const stored = await fileStorage.getStirlingFileStub(originalFileId);
if (!stored) throw new Error('File was never stored; import it first.');
// fall back to a no-history upload path
return uploadSingleFile(originalFileId, existingRemoteId);
} Defensive patterns
Strategy: validation
Validate before calling
const chain = await fileStorage.getHistoryChainStubs(originalFileId);
if (chain.length === 0) {
throw new Error(`No history for ${originalFileId}; store the file first.`);
} Type guard
async function hasHistoryChain(id: FileId): Promise<boolean> {
return (await fileStorage.getHistoryChainStubs(id)).length > 0;
} Prevention
- Always store a file via storeStirlingFile (which sets originalFileId) before offering share/upload actions.
- Disable the share/upload UI action when getHistoryChainStubs is empty.
When it happens
Trigger: uploadHistoryChain is called with an originalFileId that was never persisted via storeStirlingFile, whose originalFileId linkage is unset, or whose records were cleared.
Common situations: Passing a raw File/FileId straight to upload without storing it first; user cleared site data; a freshly-imported leaf whose originalFileId was not set to itself; storage eviction removed all versions.
Related errors
- Missing final file data for sharing.
- File not found
- File not found in storage: ${fileStub.name} (ID: ${fileStub.
- File not found in storage: ${stub.name}
- No history chain found for file.
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/c70af7dfa9376628.
Report an issue: GitHub.