{"record":{"id":"c70af7dfa9376628","repo":"Stirling-Tools/Stirling-PDF","slug":"no-history-chain-found","errorCode":null,"errorMessage":"No history chain found.","messagePattern":"No history chain found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/services/serverStorageUpload.ts","lineNumber":27,"sourceCode":"\nfunction resolveUpdatedAt(value: unknown): number {\n  if (!value) {\n    return Date.now();\n  }\n  if (typeof value === \"number\") {\n    return Number.isFinite(value) ? value : Date.now();\n  }\n  const parsed = new Date(String(value)).getTime();\n  return Number.isFinite(parsed) ? parsed : Date.now();\n}\n\nexport async function uploadHistoryChain(\n  originalFileId: FileId,\n  existingRemoteId?: number,\n): Promise<{ remoteId: number; updatedAt: number; chain: StirlingFileStub[] }> {\n  const chain = await fileStorage.getHistoryChainStubs(originalFileId);\n  if (chain.length === 0) {\n    throw new Error(\"No history chain found.\");\n  }\n\n  const finalStub =\n    chain\n      .slice()\n      .reverse()\n      .find((stub) => stub.isLeaf !== false) || chain[chain.length - 1];\n  const finalFile = await fileStorage.getStirlingFile(finalStub.id);\n  if (!finalFile) {\n    throw new Error(\"Missing final file data for sharing.\");\n  }\n\n  const { bundleFile, manifest } = await buildHistoryBundle(originalFileId);\n  const auditLog = new File(\n    [JSON.stringify(manifest, null, 2)],\n    \"audit-log.json\",\n    {\n      type: \"application/json\",","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/services/serverStorageUpload.ts#L9-L45","documentation":"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.","triggerScenarios":"uploadHistoryChain is called with an originalFileId that was never persisted via storeStirlingFile, whose originalFileId linkage is unset, or whose records were cleared.","commonSituations":"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.","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."],"exampleFix":"// before\nconst chain = await fileStorage.getHistoryChainStubs(originalFileId);\nif (chain.length === 0) throw new Error('No history chain found.');\n\n// after\nconst chain = await fileStorage.getHistoryChainStubs(originalFileId);\nif (chain.length === 0) {\n  // ensure the file is stored and self-linked as its own root\n  const stored = await fileStorage.getStirlingFileStub(originalFileId);\n  if (!stored) throw new Error('File was never stored; import it first.');\n  // fall back to a no-history upload path\n  return uploadSingleFile(originalFileId, existingRemoteId);\n}","handlingStrategy":"validation","validationCode":"const chain = await fileStorage.getHistoryChainStubs(originalFileId);\nif (chain.length === 0) {\n  throw new Error(`No history for ${originalFileId}; store the file first.`);\n}","typeGuard":"async function hasHistoryChain(id: FileId): Promise<boolean> {\n  return (await fileStorage.getHistoryChainStubs(id)).length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always store a file via storeStirlingFile (which sets originalFileId) before offering share/upload actions.","Disable the share/upload UI action when getHistoryChainStubs is empty."],"tags":["indexeddb","file-storage","history-chain","sharing"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}