dify - ✅(Solved) Fix Embedded chatbot ignores URL conversation_id parameter when localStorage has a stored value [1 pull requests, 1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
langgenius/dify#35489Fetched 2026-04-23 07:45:27
View on GitHub
Comments
1
Participants
1
Timeline
3
Reactions
1
Author
Participants
Timeline (top)
commented ×1cross-referenced ×1labeled ×1

Root Cause

In web/app/components/base/chat/embedded-chatbot/hooks.tsx line 116:

const currentConversationId = useMemo(
  () => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || conversationId || '',
  [appId, conversationIdInfo, userId, conversationId]
)

The priority order is localStorage > URL param. Once localStorage has a stored conversation ID (from any previous interaction), it always takes precedence over the explicitly provided URL parameter.

The fix is to swap the priority: conversationId || conversationIdInfo?.[...] || '', so the URL parameter wins when present, and localStorage serves as a fallback when no URL param is provided.

Fix Action

Fixed

PR fix notes

PR #35505: fix(web): prioritize URL conversation_id over localStorage in embedde…

Description (problem / solution / changelog)

The pull request addresses a critical bug in the embedded chatbot where the application prioritizes conversation ID information stored in the local storage over explicit parameters passed via the URL. By swapping the priority logic within the useMemo hook in the hooks.tsx file, this change ensures that the conversationId provided by the developer through the embed script takes precedence as the primary source of truth while maintaining the local storage as a fallback mechanism for session persistence. This modification effectively resolves issue number 35489 and provides a comprehensive fix for related bugs number 33362 and 34731 which involve stuck conversation states and infinite 404 error loops caused by stale session data. The implementation allows parent websites to programmatically control and switch chat sessions as intended without requiring users to manually clear their browser cache to start a new conversation.

Fixes #35489

Changed files

  • web/app/components/base/chat/embedded-chatbot/hooks.tsx (modified, +2/-2)

Code Example

const currentConversationId = useMemo(
  () => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || conversationId || '',
  [appId, conversationIdInfo, userId, conversationId]
)
RAW_BUFFERClick to expand / collapse

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

v1.13.3

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

  1. Deploy a Dify Chatflow app and embed it into a website using embed.min.js
  2. Pass a conversation_id as a system variable parameter via embed.js config
  3. The iframe is created with the conversation_id encoded in the URL
  4. Send a message in the embedded chatbot — this stores the conversation ID in localStorage (conversationIdInfo)
  5. Now pass a different conversation_id via embed.js (e.g. to start a new conversation)
  6. Reload the page with the new parameter

✔️ Expected Behavior

The embedded chatbot should use the conversation_id provided via the URL parameter from embed.js, allowing the parent website to control which conversation is loaded.

❌ Actual Behavior

The embedded chatbot ignores the URL conversation_id and always uses the value stored in localStorage (conversationIdInfo). This prevents the parent website from switching conversations or starting new ones via embed.js parameters.

Root Cause

In web/app/components/base/chat/embedded-chatbot/hooks.tsx line 116:

const currentConversationId = useMemo(
  () => conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || conversationId || '',
  [appId, conversationIdInfo, userId, conversationId]
)

The priority order is localStorage > URL param. Once localStorage has a stored conversation ID (from any previous interaction), it always takes precedence over the explicitly provided URL parameter.

The fix is to swap the priority: conversationId || conversationIdInfo?.[...] || '', so the URL parameter wins when present, and localStorage serves as a fallback when no URL param is provided.

Related Issues

  • #33362 — Reset button does not clear conversationIdInfo, preventing new conversations
  • #34731 — Stale conversation_id in localStorage causes infinite 404 loop

All three issues share a common root cause: conversationIdInfo in localStorage is given unconditional priority over other conversation ID sources.

extent analysis

TL;DR

Update the useMemo hook in embedded-chatbot/hooks.tsx to prioritize the URL parameter conversationId over the conversationIdInfo stored in localStorage.

Guidance

  • Identify the line of code causing the issue: web/app/components/base/chat/embedded-chatbot/hooks.tsx line 116.
  • Update the useMemo hook to change the priority order: conversationId || conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || ''.
  • Verify the fix by testing the embedded chatbot with different conversation_id parameters via embed.js and checking that the correct conversation is loaded.
  • Consider addressing related issues (#33362 and #34731) to ensure a consistent conversation ID management.

Example

const currentConversationId = useMemo(
  () => conversationId || conversationIdInfo?.[appId || '']?.[userId || 'DEFAULT'] || '',
  [appId, conversationId, conversationIdInfo, userId]
)

Notes

This fix assumes that the conversationId parameter is always provided via the URL when a new conversation is intended to be started. If this is not the case, additional logic may be needed to handle cases where no conversationId parameter is provided.

Recommendation

Apply the workaround by updating the useMemo hook to prioritize the URL parameter conversationId. This should resolve the issue and allow the parent website to control which conversation is loaded.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING