Skip to content

fix(flowchat): report an unreadable session permission mode - #3169

Merged
nonoqing merged 1 commit into
GCWing:mainfrom
nonoqing:fix/session-permission-mode-unread
Sep 21, 2026
Merged

nonoqing merged 1 commit into
GCWing:mainfrom
nonoqing:fix/session-permission-mode-unread

Conversation

@nonoqing

Copy link
Copy Markdown
Collaborator

Summary

A Session whose permission mode cannot be read now says so, and a failed switch names the cause instead of reporting a generic failure.

Fixes #

Type and Areas

Type: bug fix / regression fix.

Areas: desktop/Tauri, web UI.

Motivation / Impact

A user upgraded from 1.0.0 to 1.0.1, opened a Session created on 1.0.0, and saw its permission mode change to "Ask" even though the Session had been set to full access. Switching it back failed with a generic error, while a newly created Session switched normally. No setting was actually lost.

The real error was session_in_use: Session is already open for writing: <session_id> — the previous OpenBitFun instance was still running and held the per-Session write lock. Three separate presentation defects turned that into a phantom setting loss:

  1. get_session_permission_mode failing is swallowed with setSessionPermissionMode(null), so the control silently falls back to the user-level default (ask in this case) and displays it as the Session's own selection.
  2. update_session_permission_mode failing reports chatInput.permissionMode.changeFailed, which says nothing about the cause or what to do.
  3. ensure_session_loaded_for_selector_update wrapped the error as Failed to restore session before selector update: {error}, burying the stable session_in_use code that the frontend recognizes by message prefix. isSessionInUseError therefore returned false for this path.

What changes for users:

  • A failed read is marked as unread: the tooltip says the shown mode is the default, the menu marks no mode (the fallback is not the Session's choice) and explains why, and one notification per Session reports the fallback.
  • When the host reports session_in_use, the read and switch messages name the other instance and ask the user to close it.
  • session_in_use and outcome_unknown keep their stable code prefix through the selector-update restore, so the frontend can tell them apart from a generic restore failure. Every other reason keeps the Failed to restore session before selector update: context.

New user-facing keys: changeFailedSessionInUse, unread, unreadSessionInUse, unreadTooltip, unreadMenuNotice (en-US, zh-CN, zh-TW).

No behavior change to which mode a Session actually runs with: the fallback remains the narrow default, never a wider mode than the Session uses.

Verification

  • pnpm run type-check:web — passed.
  • pnpm run i18n:audit — passed with 0 warnings.
  • pnpm run fmt:rs — formatted.
  • cargo test -p openbitfun-desktop selector_update_restore_error — 3 passed (new tests pin the preserved session_in_use / outcome_unknown prefixes and the retained context for other reasons).
  • pnpm vitest run src/flow_chat/components/ChatInputWorkspaceStrip.test.tsx — 31 passed, including a new case that mounts the unread state and asserts no mode radio is marked plus the menu notice is present.
  • pnpm vitest run src/flow_chat/components/ChatInputWorkspaceStripLayout.test.ts src/flow_chat/components/chatInputRegistration.test.ts src/flow_chat/components/overlayClippingContract.test.ts src/infrastructure/api/errors/TauriCommandError.test.ts — 71 passed.
  • npx eslint src/flow_chat/components/ChatInput.tsx src/flow_chat/components/ChatInputWorkspaceStrip.tsx — 0 errors.

Remote scenarios: not exercised. The permission selector reads and writes through the desktop host only; the change does not add a new command, wire field, or persisted shape.

Upgrade compatibility: no persisted shape changes. The error message shape changes only for the two stable codes, which the frontend recognizes by prefix; older frontends still see a readable message.

Reviewer Notes

  • The frontend reuses the existing isSessionInUseError helper from @/infrastructure/api/errors/TauriCommandError rather than adding a second string match; the Rust test pins the prefix shape it depends on.
  • The notification is deduplicated per Session id and cleared after a successful read or switch, so a flapping state re-reports but an unresolved one does not repeat on every effect run.
  • Scope is limited to the permission selector path (get_session_permission_mode, update_session_permission_mode, update_active_turn_permission_mode). Other commands that flatten error codes are untouched.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable.

A Session whose permission mode cannot be read falls back to the user-level
default, and that fallback was displayed as if the Session had chosen it.
Together with a generic switch failure it made a Session held open for
writing by another OpenBitFun instance look like a lost setting.

Mark the fallback as unread instead of passing it off as the Session's own
selection: report it once per Session, name the cause when the host reports
session_in_use, keep the permission menu from marking an unverified mode,
and point the switch failure at the other instance.

Stop wrapping session_in_use and outcome_unknown in the selector-update
prose so their stable error codes reach the frontend, which recognizes
those two by message prefix.

Co-authored-by: bitfun-ai <318544290+bitfun-ai@users.noreply.github.com>
@nonoqing
nonoqing merged commit 41beb1a into GCWing:main Sep 21, 2026
13 checks passed
@nonoqing
nonoqing deleted the fix/session-permission-mode-unread branch September 21, 2026 07:25
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.

1 participant