{"record":{"id":"2913fe01db0e6639","repo":"mickael-kerjean/filestash","slug":"missing-key","errorCode":null,"errorMessage":"Missing Key","messagePattern":"Missing Key","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/plugin/plg_widget_pgp/assets/pgp.js","lineNumber":42,"sourceCode":"            <style>${CSS}</style>\n        </div>\n    `);\n    const encrypted = await new Promise(async (done, error) => {\n        try {\n            const res = await fetch(src);\n            done(await res.arrayBuffer());\n        } catch (err) {\n            error(err);\n        }\n    });\n    if (encrypted.byteLength === 0) {\n        return URL.createObjectURL(new Blob([encrypted]));\n    }\n    return new Promise((done) => createModal({ withButtonsRight: \"decrypt\", withButtonsLeft: \"cancel\" })($page, async (n) => {\n        if (n !== MODAL_RIGHT_BUTTON) return done(src);\n        try {\n            const file = qs($page, \"input\").files?.[0];\n            if (!file) throw new Error(\"Missing Key\");\n            const privateKey = await openpgp.readPrivateKey({\n                armoredKey: await file.text(),\n            });\n            KEY = privateKey;\n            const { data } = await openpgp.decrypt({\n                message: await openpgp.readMessage({\n                    binaryMessage: new Uint8Array(encrypted),\n                }),\n                decryptionKeys: privateKey,\n                format: \"binary\",\n            });\n            done(URL.createObjectURL(new Blob([data])));\n        } catch (err) {\n            notification.error(err);\n            done(src);\n        } finally {\n            $page.remove();\n        }","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/mickael-kerjean/filestash/blob/78f756eb94ef383f1f1cd4bc3077a43a4d088ff0/server/plugin/plg_widget_pgp/assets/pgp.js#L24-L60","documentation":"Thrown by the PGP widget's decode flow when a fetched encrypted resource has byteLength === 0. It is a sentinel guard meaning the fetch succeeded but the source contained no data, so there is nothing to decrypt; the widget returns a Blob URL for the empty buffer instead of entering the decrypt modal.","triggerScenarios":"Thrown at server/plugin/plg_widget_pgp/assets/pgp.js:42 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the source URL points to a non-empty PGP-encrypted file and that the upload/write step actually persisted content","Fetch the resource manually (curl/wget) to confirm it returns bytes","Check that the storage backend is not returning empty bodies for missing or truncated files","Include the source URL in the error message to identify the empty resource"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"78f756eb94ef383f1f1cd4bc3077a43a4d088ff0","analyzedAt":"2026-09-06T11:52:48.712Z","contentChangedAt":"2026-09-06T11:52:48.712Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}