Skip to content

🔁 fix: Keep the Error Card When a Stream Reattached Without Resume State Fails - #17112

Merged
berry-13 merged 1 commit into
devfrom
refactor/chat-resumable-resume
Oct 15, 2026
Merged

berry-13 merged 1 commit into
devfrom
refactor/chat-resumable-resume

Conversation

@berry-13

Copy link
Copy Markdown
Collaborator

Pull Request

Before submitting, please review the Contributing Guide.

Documentation changes belong in the LibreChat documentation repository.

Summary

When the stream status route answers a running job without resumeState (an older server, or a status that omits it), useResumeOnLoad attaches with a minimal submission whose placeholder response has no isCreatedByUser and no parent. If the reattached stream then reports a failure, building the error turn from that placeholder throws a ZodError (isCreatedByUser is required), so the error card is never written and the pane stays submitted. The placeholder is now a parented assistant row (isCreatedByUser: false, parented under the last user turn), and the fallback user row is marked as the user's, so the failure renders as an error like any other. Fixes berry-13#223.

The fix lands where the resume rules now live: the resume-state helpers (rebuilding a submission from resume state or from a bare status, matching a submission to its resume state, the branch to restore, and the merge of a resumed pair into history) move out of useResumeOnLoad.ts and useResumableSSE.ts into packages/chat/src/core/resumable/resume.ts, and the pending-action appliers they use move from utils/approval.ts to packages/chat/src/core/pending.ts, which utils/approval.ts re-exports. Apart from the fix, no behavior changes. Stacked on #17110.

Type of change

  • Bug fix
  • Refactor

Testing

Tested environments/configuration:

The failure path needs a status without resumeState, which current servers do not send, so it is covered by the spec below rather than by hand.

Automated tests:

  • transport.spec.tsx (resume): reattaches through a status without resumeState, emits an error on the stream, and expects the chat to settle on that error. It fails on the base with the ZodError and passes with the fix.
  • Added packages/chat/src/core/__tests__/resume.spec.ts for the moved resume helpers and the minimal submission.
  • npx jest src/core in packages/chat, and in client the hooks/SSE, hooks/Chat and hooks/Agents specs, utils/approval.spec.ts and PendingSteers.test.tsx: all pass.
  • npx tsc --noEmit in packages/chat and client, eslint, prettier and sort-imports on the changed files: clean.

Screenshots / recordings

No user-facing change.

Risk / compatibility

None. utils/approval.ts keeps exporting the pending-action appliers, now from @librechat/chat.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T15:25:42.602270Z 79364f3 New commits
🔒 Security Review ✅ Completed 2026-10-15T05:51:42.825469Z d88d6f6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codegraph-librechat codegraph-librechat Bot added the 🗺️ Chat State codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 15, 2026
@berry-13
berry-13 added this pull request to stack #17153 October 15, 2026 13:49
@berry-13
berry-13 force-pushed the refactor/chat-resumable-resume branch from d88d6f6 to c9721d1 Compare October 15, 2026 15:03
Copilot AI balanced review requested due to automatic review settings October 15, 2026 15:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9721d1923

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +503 to +504
messages,
userMessage,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid appending the resumed user row twice

When a bare-status reattach finds lastUserMessage, that exact row is already present in messages, but the submission retains the full array and sets isRegenerate: false. If the reattached stream emits the error this change targets, errorHandler calls mergeErrorMessages, whose normal path returns [...messages, userMessage, errorMessage]; this duplicates the prompt (including its messageId) in the rendered and React Query-cached transcript. Exclude the selected user row from the submission prefix, or otherwise use a merge path that appends only the error for this resume case.

AGENTS.md reference: AGENTS.md:L50-L53

Useful? React with 👍 / 👎.

@berry-13
berry-13 force-pushed the refactor/chat-resumable-resume branch from c9721d1 to ffcbe71 Compare October 15, 2026 15:19
Base automatically changed from refactor/chat-resumable-messages to dev October 15, 2026 15:20
@berry-13
berry-13 force-pushed the refactor/chat-resumable-resume branch from ffcbe71 to 79364f3 Compare October 15, 2026 15:20
@berry-13
berry-13 merged commit 0354562 into dev Oct 15, 2026
30 checks passed
@berry-13
berry-13 deleted the refactor/chat-resumable-resume branch October 15, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗺️ Chat State codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants