Skip to content

🧭 fix: Robust 404 Conversation Not Found Redirect#11853

Merged
danny-avila merged 6 commits intodevfrom
fix/convo-not-found-redirect
Feb 18, 2026
Merged

🧭 fix: Robust 404 Conversation Not Found Redirect#11853
danny-avila merged 6 commits intodevfrom
fix/convo-not-found-redirect

Conversation

@danny-avila
Copy link
Owner

@danny-avila danny-avila commented Feb 18, 2026

Summary

I added robust handling for when a user navigates to a conversation URL that no longer exists, replacing silent retry loops with an immediate redirect and a user-facing toast notification.

  • Created client/src/utils/errors.ts exporting getResponseStatus, which extracts an HTTP status code from either an Axios error or a plain object with a status property, and isNotFoundError, which returns true when that status is 404; re-exported both through client/src/utils/index.ts.
  • Added a retry function to useGetConvoIdQuery that immediately short-circuits with false on 404 errors, eliminating the exponential-backoff retry delay that previously stalled error-state surfacing.
  • Added an error branch to the ChatRoute initialization effect that fires when initialConvoQuery.isError is true and isNotFoundError confirms a 404, displays a WARNING severity toast with the new com_ui_conversation_not_found locale key, and calls newConversation() to redirect to a fresh conversation.
  • Added initialConvoQuery.isError to the effect's dependency array so the effect correctly re-runs when the query transitions into an error state.
  • Added the "com_ui_conversation_not_found": "Conversation not found" key to the English locale file.

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

To test, navigate directly to a conversation URL with a deleted or otherwise non-existent conversation ID (e.g., /c/some-invalid-id). Confirm:

  1. A "Conversation not found" warning toast is displayed.
  2. The app redirects immediately to a new conversation (/c/new).
  3. Only a single network request is made for the invalid ID — no retries occur before the redirect.
  4. Navigating to a valid, existing conversation still loads correctly.
  5. Simulate a non-404 network failure (e.g., 500 or offline) on the conversation fetch and confirm the query still retries up to 3 times before entering the error state.

Test Configuration

  • Any authenticated session with access to at least one existing conversation.

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings

dlew and others added 3 commits February 18, 2026 10:18
- Extract `isNotFoundError` utility to `utils/errors.ts` so axios stays
  contained in one place rather than leaking into route/query layers
- Add `initialConvoQuery.isError` to the useEffect dependency array so
  the redirect actually fires when the 404 response arrives after other
  deps have already settled (was the root cause of the blank screen)
- Show a warning toast so users understand why they were redirected
- Add `com_ui_conversation_not_found` i18n key
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a shared 404-detection utility and uses it to improve UX and query behavior when a requested conversation ID no longer exists.

Changes:

  • Introduces getResponseStatus / isNotFoundError utilities and re-exports them via ~/utils.
  • Updates conversation-by-id query to stop retrying on HTTP 404.
  • Updates ChatRoute to toast + create a new conversation when the initial conversation fetch returns 404, and adds an English translation string.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
client/src/utils/index.ts Re-exports new error helpers from the utils barrel.
client/src/utils/errors.ts Adds HTTP-status extraction helpers for unknown error shapes.
client/src/data-provider/queries.ts Disables react-query retries for 404 when fetching a conversation by id.
client/src/routes/ChatRoute.tsx On 404, shows a warning toast and starts a new conversation flow.
client/src/locales/en/translation.json Adds English string for “Conversation not found”.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +5 to +14
* HTTP client used. Handles Axios errors first, then falls back to checking
* for a plain `status` property so callers never need to import axios.
*/
export const getResponseStatus = (error: unknown): number | undefined => {
if (axios.isAxiosError(error)) {
return error.response?.status;
}
if (error != null && typeof error === 'object' && 'status' in error) {
return (error as { status: number }).status;
}
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getResponseStatus's fallback path only checks a top-level status property and assumes it's a number. In this codebase, many non-axios checks look at error.response?.status; as written, those errors will return undefined even when an HTTP status is present, and a non-numeric status value would be incorrectly cast. Consider extending the fallback to also handle { response: { status } } and guarding typeof status === 'number' before returning it (and update the docstring accordingly).

Suggested change
* HTTP client used. Handles Axios errors first, then falls back to checking
* for a plain `status` property so callers never need to import axios.
*/
export const getResponseStatus = (error: unknown): number | undefined => {
if (axios.isAxiosError(error)) {
return error.response?.status;
}
if (error != null && typeof error === 'object' && 'status' in error) {
return (error as { status: number }).status;
}
* HTTP client used. Handles Axios errors first, then falls back to checking
* for a numeric `status` property on the error itself or on `error.response`,
* so callers never need to import axios.
*/
export const getResponseStatus = (error: unknown): number | undefined => {
if (axios.isAxiosError(error)) {
return error.response?.status;
}
if (error != null && typeof error === 'object') {
// First, check for a top-level numeric `status` property.
const topLevelStatus = (error as { status?: unknown }).status;
if (typeof topLevelStatus === 'number') {
return topLevelStatus;
}
// Then, check for a nested `response.status` pattern used by some clients.
if ('response' in error) {
const response = (error as { response?: { status?: unknown } }).response;
const nestedStatus = response?.status;
if (typeof nestedStatus === 'number') {
return nestedStatus;
}
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +109
} else if (initialConvoQuery.isError && isNotFoundError(initialConvoQuery.error)) {
showToast({
message: localize('com_ui_conversation_not_found'),
severity: NotificationSeverity.WARNING,
});
newConversation();
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the 404 branch, newConversation() is called without waiting for endpointsQuery.data/modelsQuery.data (unlike the other branches), but useNewConvo may attempt to build a default conversation using endpoints/models data that may not be loaded yet. If endpoints config isn't available yet, this can result in a conversation with endpoint becoming undefined (see buildDefaultConvo's early return when endpoint is falsy) and hasSetConversation.current being set to true, which would prevent later initialization once queries complete. Also, since the route uses c/:conversationId?, navigating to /c yields an empty conversationId which will likely 404 and trigger this toast/redirect even though it's not really a missing conversation. Consider guarding this branch with conversationId truthiness and gating on endpointsQuery.data && modelsQuery.data (or passing modelsData: modelsQuery.data) before setting hasSetConversation.current.

Suggested change
} else if (initialConvoQuery.isError && isNotFoundError(initialConvoQuery.error)) {
showToast({
message: localize('com_ui_conversation_not_found'),
severity: NotificationSeverity.WARNING,
});
newConversation();
} else if (
initialConvoQuery.isError &&
isNotFoundError(initialConvoQuery.error) &&
conversationId &&
endpointsQuery.data &&
modelsQuery.data
) {
showToast({
message: localize('com_ui_conversation_not_found'),
severity: NotificationSeverity.WARNING,
});
newConversation({
modelsData: modelsQuery.data,
});

Copilot uses AI. Check for mistakes.
- Update the getResponseStatus function to ensure it correctly returns the status from error objects only if the status is a number. This improves robustness in error handling by preventing potential type issues.
- Enhance error handling when a conversation is not found by checking additional conditions before showing a warning toast.
- Update the newConversation function to include model data and preset options, improving user experience during error scenarios.
- Added logging for the initial conversation query error when a conversation is not found, improving debugging capabilities and error tracking in the ChatRoute component.
@danny-avila danny-avila changed the title feat: Robust 404 Conversation Redirect Handling 🧭 fix: Robust 404 Conversation Not Found Redirect Feb 18, 2026
@danny-avila danny-avila merged commit 42718fa into dev Feb 18, 2026
5 checks passed
@danny-avila danny-avila deleted the fix/convo-not-found-redirect branch February 18, 2026 16:41
JumpLink pushed a commit to faktenforum/LibreChat that referenced this pull request Feb 19, 2026
* fix: route to new conversation when conversation not found

* Addressed PR feedback

* fix: Robust 404 conversation redirect handling

- Extract `isNotFoundError` utility to `utils/errors.ts` so axios stays
  contained in one place rather than leaking into route/query layers
- Add `initialConvoQuery.isError` to the useEffect dependency array so
  the redirect actually fires when the 404 response arrives after other
  deps have already settled (was the root cause of the blank screen)
- Show a warning toast so users understand why they were redirected
- Add `com_ui_conversation_not_found` i18n key

* fix: Enhance error handling in getResponseStatus function

- Update the getResponseStatus function to ensure it correctly returns the status from error objects only if the status is a number. This improves robustness in error handling by preventing potential type issues.

* fix: Improve conversation not found handling in ChatRoute

- Enhance error handling when a conversation is not found by checking additional conditions before showing a warning toast.
- Update the newConversation function to include model data and preset options, improving user experience during error scenarios.

* fix: Log error details for conversation not found in ChatRoute

- Added logging for the initial conversation query error when a conversation is not found, improving debugging capabilities and error tracking in the ChatRoute component.

---------

Co-authored-by: Dan Lew <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants