- OpenPGP.js version:
5.5.0
- Affected platform (Browser or Node.js version): > Node 20.x.x
When we switched from node 18 to node 20 we've encountered this problem, where decrypt method resolves the promise, but the data does not contain a decrypted stream.
The code reads a file using a stream with the fs.createReadStream method. If the stream isn't properly closed (either because of an error, or because the stream wasn't fully read), the file remains open. In the original code, we were passing the stream directly to openpgp.readMessage, and if openpgp.readMessage didn't read the stream fully or there was an error in between, the stream was left open.
The piece of code:
const stream = fs.createReadStream(filePath, 'utf-8');
const privateKey = await openpgp.decryptKey({
privateKey: await openpgp.readPrivateKey({
armoredKey: this.privateKeyASCII,
}),
passphrase: this.passPhrase,
});
const options: openpgp.DecryptOptions = {
decryptionKeys: privateKey,
message: await openpgp.readMessage({
armoredMessage: stream,
}),
};
const { data } = await openpgp.decrypt(options);
return data;

Solution:
To resolve the issue, we explicitly close the stream using the stream.destroy() method after we're done processing it. This ensures that the file descriptor is closed and released appropriately, and it doesn't have to wait for the garbage collector to do it.
5.5.0When we switched from node 18 to node 20 we've encountered this problem, where
decryptmethod resolves the promise, but thedatadoes not contain a decrypted stream.The code reads a file using a stream with the
fs.createReadStreammethod. If the stream isn't properly closed (either because of an error, or because the stream wasn't fully read), the file remains open. In the original code, we were passing the stream directly toopenpgp.readMessage, and ifopenpgp.readMessage didn't read the stream fully or there was an error in between, the stream was left open.The piece of code:
Solution:
To resolve the issue, we explicitly close the stream using the
stream.destroy()method after we're done processing it. This ensures that the file descriptor is closed and released appropriately, and it doesn't have to wait for the garbage collector to do it.