fix: only cap message expiry to the parent on message-only saves

Capping every forced message save to the parent expiry broke the normal send
paths: POST /api/messages/:conversationId and BaseClient.saveMessageToDatabase
call saveConvo right after saveMessage, refreshing the conversation to a fresh
TTL. The message kept the older parent deadline, so the message TTL index could
delete the just-sent message while the conversation stayed visible until the
later deadline.

Gate the cap behind a capExpiryToConversation flag that only the message-only
callers (branch, artifact, abort) set, since those never run saveConvo. Normal
sends leave the message on its fresh deadline, which the following saveConvo
refresh keeps aligned. The conversion/re-cap cascade still runs for every forced
save.
This commit is contained in:
Marco Beretta 2026-06-22 09:39:09 +02:00
parent ec8eec6eaf
commit fd8292669d
No known key found for this signature in database
GPG key ID: D918033D8E74CC11
4 changed files with 47 additions and 19 deletions

View file

@ -173,7 +173,7 @@ async function abortMessage(req, res) {
interfaceConfig: req?.config?.interfaceConfig,
},
{ ...responseMessage, user: userId },
{ context: 'api/server/middleware/abortMiddleware.js' },
{ context: 'api/server/middleware/abortMiddleware.js', capExpiryToConversation: true },
);
// Get conversation for title

View file

@ -175,7 +175,7 @@ router.post('/branch', configMiddleware, async (req, res) => {
interfaceConfig: req?.config?.interfaceConfig,
},
newMessage,
{ context: 'POST /api/messages/branch' },
{ context: 'POST /api/messages/branch', capExpiryToConversation: true },
);
if (!savedMessage) {
@ -256,7 +256,7 @@ router.post('/artifact/:messageId', configMiddleware, async (req, res) => {
content: message.content,
user: req.user.id,
},
{ context: 'POST /api/messages/artifact/:messageId' },
{ context: 'POST /api/messages/artifact/:messageId', capExpiryToConversation: true },
);
res.status(200).json({