{"record":{"id":"9c3e392a79987bcd","repo":"Stirling-Tools/Stirling-PDF","slug":"file-not-found","errorCode":null,"errorMessage":"File not found","messagePattern":"File not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/core/hooks/signing/useSigningSessionController.ts","lineNumber":424,"sourceCode":"  };\n\n  // --- Create a new signing request from the currently selected file ---\n\n  const createSession = async (\n    signatureSettings: SignatureSettings,\n    selectedUserIds: number[],\n    dueDate: string,\n  ): Promise<boolean> => {\n    if (selectedUserIds.length === 0 || selectedFiles.length !== 1) {\n      return false;\n    }\n    setCreating(true);\n    try {\n      const selectedFile = selectedFiles[0];\n      const stirlingFile = await fileStorage.getStirlingFile(\n        selectedFile.fileId,\n      );\n      if (!stirlingFile) throw new Error(\"File not found\");\n\n      const formData = new FormData();\n      formData.append(\"file\", stirlingFile, selectedFile.name);\n      formData.append(\"workflowType\", \"SIGNING\");\n      formData.append(\"documentName\", selectedFile.name);\n      selectedUserIds.forEach((userId, index) => {\n        formData.append(`participantUserIds[${index}]`, userId.toString());\n      });\n      if (dueDate) formData.append(\"dueDate\", dueDate);\n      formData.append(\"notifyOnCreate\", \"true\");\n      if (signatureSettings.includeSummaryPage) {\n        formData.append(\n          \"workflowMetadata\",\n          JSON.stringify({ includeSummaryPage: true }),\n        );\n      }\n\n      await apiClient.post(\"/api/v1/security/cert-sign/sessions\", formData);","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/core/hooks/signing/useSigningSessionController.ts#L406-L442","documentation":"Thrown in `createSession` (the signing-workflow creation path) after `fileStorage.getStirlingFile(selectedFile.fileId)` returns a falsy value. The user selected exactly one file in the UI, but when the controller asks IndexedDB for the full StirlingFile blob, none comes back — the file stub is dangling relative to persisted storage.","triggerScenarios":"File was selected but later evicted by the IndexedDB LRU cache; the browser cleared site data / storage between selection and 'Create session'; a stale selected-file reference survived a FileContext reset; the fileId points to a superseded version whose storage was orphaned and deleted.","commonSituations":"Long sessions where many large PDFs pushed the chosen file out of the LRU; user opened devtools and cleared storage; restored a selection state from a previous session via URL/history.","solutions":["Re-derive the StirlingFile from disk via the file picker / drag-drop rather than trusting a stale fileId when getStirlingFile returns null.","Validate the selected file is still present in storage before enabling the 'Create' button (poll fileStorage.hasFile).","Show a user-facing alert ('This file is no longer available, please re-add it') instead of throwing raw — createSession already toasts on error, so ensure the message is human-readable.","Increase the IndexedDB LRU cap if eviction is the recurring cause."],"exampleFix":"// before\nconst stirlingFile = await fileStorage.getStirlingFile(selectedFile.fileId);\nif (!stirlingFile) throw new Error(\"File not found\");\n\n// after — surface a recoverable, typed error\nconst stirlingFile = await fileStorage.getStirlingFile(selectedFile.fileId);\nif (!stirlingFile) {\n  throw new Error(t(\"signSession.fileMissing\", \"The selected file is no longer available. Please re-add it and try again.\"));\n}","handlingStrategy":"validation","validationCode":"// Verify the selected file is still in storage before creating the session\nconst present = selectedFile.fileId ? await fileStorage.hasFile?.(selectedFile.fileId) : false;\nif (!present) {\n  // re-prompt the user to re-add the file; do not call createSession\n}","typeGuard":"function hasStirlingFile(r: StirlingFile | null | undefined): r is StirlingFile {\n  return !!r && r instanceof File;\n}","tryCatchPattern":"try {\n  await createSession(signatureSettings, selectedUserIds, dueDate);\n} catch (e) {\n  if (e instanceof Error && e.message === \"File not found\") {\n    alert({ alertType: \"error\", title: t(\"common.error\"), body: t(\"signSession.fileMissing\", \"The selected file is no longer available. Please re-add it.\") });\n  } else { throw e; }\n}","preventionTips":["Disable 'Create session' until the selected file is confirmed present in IndexedDB.","Prune file stubs from selection state when their storage is removed so they cannot be acted on.","Increase the IndexedDB LRU cap to reduce eviction of in-use files."],"tags":["signing","indexeddb","file-storage","stale-state"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}