danny-avila/LibreChat · error · Error
Conversation not found
Error message
Conversation not found
What it means
Thrown by duplicateConversation (utils/import/fork.js) when getConvo(userId, conversationId) returns null. The conversation either does not exist, was deleted, or does not belong to the requesting user (getConvo scopes by user), so there is nothing to duplicate.
Source
Thrown at api/server/utils/import/fork.js:532
return {
conversation,
messages,
};
});
}
/**
* Duplicates a conversation and all its messages.
* @param {object} params - The parameters for duplicating the conversation.
* @param {string} params.userId - The ID of the user duplicating the conversation.
* @param {string} params.conversationId - The ID of the conversation to duplicate.
* @param {string} [params.title] - Optional title override for the duplicate.
* @returns {Promise<{ conversation: TConversation, messages: TMessage[] }>} The duplicated conversation and messages.
*/
async function duplicateConversation({ userId, conversationId, title }) {
const originalConvo = await getConvo(userId, conversationId);
if (!originalConvo) {
throw new Error('Conversation not found');
}
const originalMessages = await getMessages({
user: userId,
conversationId,
});
const messagesToClone = getMessagesUpToTargetLevel(
originalMessages,
originalMessages[originalMessages.length - 1].messageId,
);
const importBatchBuilder = createImportBatchBuilder(userId);
importBatchBuilder.startConversation(originalConvo.endpoint ?? EModelEndpoint.openAI);
cloneMessagesWithTimestamps(messagesToClone, importBatchBuilder);
const duplicateTitle = title || originalConvo.title;View on GitHub (pinned to 5ff282f900)
Solutions
- Verify the conversationId exists for the user (e.g. via a presence check or by refreshing the source list) before offering the duplicate action.
- Return a 404 from the controller when getConvo yields null, instead of letting the generic error propagate.
- Confirm the authenticated user matches the conversation's owner.
Example fix
// before
await duplicateConversation({ userId, conversationId });
// after
const existing = await getConvo(userId, conversationId);
if (!existing) return res.status(404).json({ message: 'Conversation not found' });
await duplicateConversation({ userId, conversationId }); Defensive patterns
Strategy: validation
Validate before calling
const originalConvo = await getConvo(userId, conversationId);
if (!originalConvo) {
throw new Error('Conversation not found');
} Type guard
const conversationExistsForUser = async (userId, conversationId) => !!(await getConvo(userId, conversationId));
Try / catch
try {
await duplicateConversation({ userId, conversationId });
} catch (err) {
if (err.message === 'Conversation not found') return res.status(404).json({ message: err.message });
throw err;
} Prevention
- Check conversation existence before enabling the duplicate action in the UI.
- Return 404 from the controller when getConvo returns null.
- Ensure the authenticated user owns the conversation before duplicating.
When it happens
Trigger: Passing a wrong or stale conversationId; the conversation was deleted between the UI load and the duplicate click; a cross-user request where the id belongs to another user; a tenant/DB mismatch; the id is a client-generated temp id never persisted.
Common situations: Duplicate action on an already-deleted conversation; race between deletion and duplicate; misrouted request after a user switch; tests with fabricated ids.
Related errors
- Latest `messageId` is required for forking from target messa
- [${req.baseUrl}] Endpoint is required
- Agent not found
- Text is required
- Error uploading file: ${result.message}
AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12).
Data as JSON: /api/errors/7d0ef261f66fb0a9.
Report an issue: GitHub.