"ERR_INVALID_STATE" "Writer has been released" when trying to repost an attachment

I am trying to take a Message's .attachments and "repost" them attached to a new message (sent via webhook, if it matters). Upon sending, however, I get an error from deep inside the library:
TypeError [ERR_INVALID_STATE]: Invalid state: Writer has been released
(at lazyWritableReleasedError (node:internal/webstreams/writablestream:94:19)
TypeError [ERR_INVALID_STATE]: Invalid state: Writer has been released
(at lazyWritableReleasedError (node:internal/webstreams/writablestream:94:19)
The code is something like:
mywebhook.send({
embeds: Array.from( some_message.embeds, embed=>Discord.EmbedBuilder.from(embed) ),
files: Array.from( some_message.attachments.values() )
});
mywebhook.send({
embeds: Array.from( some_message.embeds, embed=>Discord.EmbedBuilder.from(embed) ),
files: Array.from( some_message.attachments.values() )
});
with no content: needed in this use-case. Note that the code works perfectly when there are no attachments. My guess is some sort of internal write-stream state is being stored somewhere and it doesn't like the attachments being reused. Against that possibility, by analogy with the embeds, I did variations on stuff like:
files: Array.from(
some_message.attachments.values(),
attachment => new Discord.AttachmentBuilder( attachment.url )
)
files: Array.from(
some_message.attachments.values(),
attachment => new Discord.AttachmentBuilder( attachment.url )
)
to no avail. The documentation has no guidance on this, and the error has evidently been reported nowhere, so I'm really just guessing at this point. What approach should I be doing? Thanks.
4 Replies
d.js toolkit
d.js toolkit8mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
imallett
imallett8mo ago
Basically, it's because .files is supposed to be an array whereas some_message.attachments is a collection. Re: using a map, it's not a big difference either way; I personally like the array form to stress the type is an array:
Array.from( some_message.embeds, embed=>Discord.EmbedBuilder.from(embed) )
Array.from( some_message.embeds, embed=>Discord.EmbedBuilder.from(embed) )
some_message.embeds.map( embed => Discord.EmbedBuilder.from(embed) )
some_message.embeds.map( embed => Discord.EmbedBuilder.from(embed) )
I guess another important thing—the
files: Array.from( some_message.attachments.values() )
files: Array.from( some_message.attachments.values() )
approach worked just fine in a previous version (I think 13.16.0). As mentioned, I tried that, mapping attachment => new Discord.AttachmentBuilder( attachment.url ). Produced same error.
imallett
imallett8mo ago
Will try the result with just the URL itself. As for the files: Array.from( some_message.attachments.values() ) approach, here is the full stack trace:
imallett
imallett8mo ago
Using files: some_message.attachments.map( attachment => attachment.url ) instead produced a similar / identical error. Well, I don't load that dependency explicitly; Discord.js uses it internally, I guess 🤷 . . . point is, maybe Discord.js's use of that package is incorrect somehow. It's not a thing I would know how to solve. I think I'm already doing what you suggested as my current workaround: I download the attachment from received_attachment.url to a temporary file on my host. Then I reupload it to an Discord.AttachmentBuilder using .setFile(...) and the rest, then send that. This works, but it's really annoying. IIUC you're saying the failure implies an issue in undici's fetch. I wouldn't know about that, but in any case this should be investigated and escalated upstream, yes? Uh, I mean at the very least one has to manually save and then reupload a file, which is significantly more code than just copying or assigning an array? That's annoying in that it's more code, which is more chance for error and more maintenance, as well as a missed amortization. Worse, though, is that such a low-level error percolated up with no context. This should not happen; exception popping shouldn't leave the context that gave it meaning; it should go up exactly to the level that has context to handle it. If that's supposed to be me (and maybe it is!), then I'm going to need a better reason than "invalid writer state", because that doesn't mean anything in my level, which concerns "copying an attachment". I'll also reiterate that this failing feels more like a bug, though, given that "copying an attachment" is a normal use-case (and indeed one that worked previously). I mean, I only have the one server I can really test this on, but it seems reliable and simple.