Repository navigation
Shared (multi-user) personal conversations 404 on load and never return an AI response #1281
Description
Issue
Once a personal conversation is shared with another user (chat_type = personal_multi_user), the conversation is unusable end to end. Two independent defects are involved:
- Every page reload or sidebar click on the shared conversation fires a
404against the personal messages endpoint and raises aConversation not founddanger toast. - Every AI request in the shared conversation fails immediately with
Stream interrupted: Chat streaming endpoint is unavailable, so the model is never invoked.
Affects all users of the Collaborative Conversations feature.
Steps to Reproduce
- Start a normal personal conversation and exchange a few messages.
- Share it with another user (Add participants), converting it to
personal_multi_user. - Reload
/chats, or click the conversation in the sidebar.- Observe the
404and the error toast.
- Observe the
- Send a message in the shared conversation (for example
@Telemetry How many TM packets have arrived since startup?).- Observe the stream error instead of a response.
Expected Behavior
- Selecting or reloading a shared conversation loads its messages from the collaboration endpoint with no failed requests and no error toast.
- Sending a message in a shared conversation streams a normal assistant response.
Actual Behavior
Console on load/select:
addChatTypeBadges: chatType="personal_multi_user", groupName="null"
GET /conversation/9f615422-.../messages?ts=... 404 (Not Found)
Error loading messages: Error: Conversation not found
at chat-messages.js:2140
at async selectConversation (chat-conversations.js:1688)
Chat transcript on send:
AI
Stream interrupted before any content was received.
⚠ Stream interrupted: Chat streaming endpoint is unavailable
Response may be incomplete. The partial content above has been saved.
Impact
The Collaborative Conversations feature is effectively broken for personal multi-user chats. There is no workaround — a shared conversation cannot be reloaded cleanly and cannot produce an AI response. Group collaborative conversations use the same stream bridge and are affected by the second defect as well.
Notes
Root cause 1 — personal-only endpoint used for collaborative conversations
selectConversation() in application/single_app/static/js/chat/chat-conversations.js calls loadMessages(conversationId) inside the collaborative branch:
if (isCollaborativeConversation && window.chatCollaboration?.activateConversation) {
await loadMessages(conversationId); // personal-only endpoint
scrollConversationViewToBottom();
await window.chatCollaboration.activateConversation(conversationId, metadata);
}loadMessages() fetches /conversation/<id>/messages, whose handler (route_frontend_conversations.get_conversation_messages) only reads cosmos_conversations_container. A collaborative conversation lives in cosmos_collaboration_conversations_container under a different id than its hidden source_conversation_id (see ensure_personal_collaboration_for_legacy_conversation), so the read always raises CosmosResourceNotFoundError → 404.
The call is also redundant: activateConversation() → loadConversationMessages() already clears #chatbox and renders the collaboration messages.
Two side effects regress because of the failing call:
updateComparisonChatUploadCatalog([])runs from thecatch, so chat uploads in shared conversations never populate the Compare/Analyze picker.updateConversationTaskDocumentsFromMessages()never runs, so task documents from the previously viewed conversation stay cached against the wrong conversation.
Root cause 2 — Blueprint migration broke the internal stream endpoint lookup
application/single_app/route_backend_collaboration.py:
internal_stream_view = current_app.view_functions.get('chat_stream_api')
if not callable(internal_stream_view):
yield _serialize_stream_error('Chat streaming endpoint is unavailable', ...)Commit 094424bc ("Harden route blueprint security policies") moved every route module onto Blueprints. app.py registers chat routes with register_route_blueprint('backend_chats', ...), so /api/chat/stream is now @bp.route(...) and its Flask endpoint key is backend_chats.chat_stream_api, not chat_stream_api. The lookup returns None and the collaborative stream short-circuits before the model is called.
current_app.view_functions is the only remaining blueprint-prefix assumption in the app — every url_for() call is already dotted.
Collateral
functional_tests/test_collaboration_shared_ai_workflow.py is already failing from the same Blueprint migration: it asserts @app.route('/api/collaboration/conversations/<conversation_id>/stream', ...), which is now @bp.route(...).
Suspected files
application/single_app/route_backend_collaboration.pyapplication/single_app/static/js/chat/chat-conversations.jsapplication/single_app/static/js/chat/chat-collaboration.jsapplication/single_app/static/js/chat/chat-messages.jsfunctional_tests/test_collaboration_shared_ai_workflow.py
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsReleased
Activity
paullizer commentedon Aug 18, 2026
Both root causes are fixed in PR #1283 (v0.250.224).
Root cause 1 —
selectConversation()called the personalloadMessages()for collaborative conversations, hitting/conversation/<id>/messages. That handler only readscosmos_conversations_container, but a shared conversation lives in the collaboration container under a different id than its hiddensource_conversation_id, so the read always 404'd. The call was redundant —activateConversation()already loads and renders the shared messages. Removed it, and moved the search highlight, task document, and comparison chat upload side effects intoloadConversationMessages()so shared conversations keep parity (this also restores chat uploads in the Compare/Analyze picker and stops stale task documents carrying over).Root cause 2 — the collaboration stream bridge resolved the internal chat stream view by the bare name
chat_stream_api, but the Blueprint security hardening moved it tobackend_chats.chat_stream_api. Added a Blueprint-tolerant_resolve_internal_view_function()that keeps the exact-match fast path, plus a[COLLABORATION]log event when resolution fails so this cannot regress silently again. Group collaborative conversations are restored by the same fix.Validation
chat_stream_apion abackend_chatsBlueprint exactly like production and asserts the resolver finds it: 6/6 passed.loadConversationMessages()in Chromium and asserts the personal endpoint is never requested: passed.ui_tests/suite went 28 → 27 failures, and functional tests referencing the changed JS went 13 → 10 — no new failures introduced; remaining ones confirmed pre-existing against stashed source.Follow-ups found but left out of scope (noted in the PR):
_serialize_stream_error()omitsconversation_kind;chat-streaming.js:1449/:1515call awindow.chatMessages.loadMessagesthat is not exported and are inert; and roughly 68 tests repo-wide still assert the pre-Blueprint@app.routeform.Fix shared multi-user conversation reload and AI streaming
Harden collaboration stream errors and repair stale route assertions
paullizer commentedon Aug 19, 2026
Shipped in v0.250.227 via #1283 and #1288.
Release note entries:
Full notes: https://microsoft.github.io/simplechat/explanation/release_notes/
Closing as completed. This issue stayed open after the fix merged because pull requests target
Developmentwhile the repository default branch ismain, so GitHub never applied theFixes #keyword automatically.