Skip to content

fix(ui): prevent WebSocket URL edit from clearing Gateway Token#41718

Closed
zheliu2 wants to merge 2 commits into
openclaw:mainfrom
zheliu2:zheliu/fix-ws-url-clears-token
Closed

fix(ui): prevent WebSocket URL edit from clearing Gateway Token#41718
zheliu2 wants to merge 2 commits into
openclaw:mainfrom
zheliu2:zheliu/fix-ws-url-clears-token

Conversation

@zheliu2

@zheliu2 zheliu2 commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: Editing the WebSocket URL field in Overview > Gateway Access immediately clears the Gateway Token field
  • Why it matters: Users lose their token every time they modify the URL, forcing them to re-enter it
  • What changed: Removed the conditional token-clearing logic from the WebSocket URL @input handler. The handler now updates only gatewayUrl without touching token.
  • What did NOT change (scope boundary): Token and password input handlers remain untouched; no other settings fields affected

Change Type (select all)

  • Bug fix

Scope (select all touched areas)

  • UI / DX

Linked Issue/PR

User-visible / Behavior Changes

Editing the WebSocket URL no longer clears the Gateway Token field.

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No — token is still stored the same way; only the input handler changed
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Any (browser-based UI)
  • Runtime/container: Any gateway
  • Integration/channel (if any): Control UI

Steps

  1. Open the Control UI Overview tab
  2. Enter a Gateway Token
  3. Edit the WebSocket URL field

Expected

  • Gateway Token remains unchanged

Actual (before fix)

  • Gateway Token is cleared on every keystroke in the WebSocket URL field

Evidence

  • Trace/log snippets

The bug was in ui/src/ui/views/overview.ts line 211:

token: v.trim() === props.settings.gatewayUrl.trim() ? props.settings.token : "",

On each keystroke, v (the new partial URL) differs from the original gatewayUrl, so the ternary always evaluates to "".

Human Verification (required)

  • Verified scenarios: Code inspection confirms the token-clearing ternary fires on every input event
  • Edge cases checked: Confirmed the token input handler and other field handlers are independent and unaffected
  • What you did not verify: Browser UI testing (Playwright not installed locally)

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: Revert this single commit
  • Files/config to restore: ui/src/ui/views/overview.ts
  • Known bad symptoms reviewers should watch for: None expected

Risks and Mitigations

None

@openclaw-barnacle openclaw-barnacle Bot added app: web-ui App: web-ui extensions: memory-lancedb Extension: memory-lancedb size: XS labels Mar 10, 2026
@zheliu2
zheliu2 force-pushed the zheliu/fix-ws-url-clears-token branch from ed48d7d to 724274e Compare March 10, 2026 13:40
@zheliu2
zheliu2 marked this pull request as ready for review March 10, 2026 14:46
@greptile-apps

greptile-apps Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR contains two independent bug fixes: the primary fix removes buggy token-clearing logic from the WebSocket URL input handler in ui/src/ui/views/overview.ts, and a secondary fix in extensions/memory-lancedb/index.ts resets the module-level lancedbImportPromise cache on failure to allow retries.

  • ui/src/ui/views/overview.ts: The fix is correct and minimal. The removed conditional was always evaluating the gateway token to an empty string on every keystroke because the live input value would never match the saved URL while the user is still typing. The handler now simply updates gatewayUrl, leaving all other settings fields untouched.
  • extensions/memory-lancedb/index.ts: Resetting lancedbImportPromise = null in the catch block is the correct fix for permanently-cached rejected promises at the module level. Note that MemoryDB.ensureInitialized stores this.initPromise and never clears it on rejection, meaning a failed doInitialize permanently breaks that MemoryDB instance regardless of this fix — see inline comment for details.

Confidence Score: 4/5

  • This PR is safe to merge; both changes are targeted bug fixes with low risk of regression.
  • The UI fix is a clean removal of clearly broken logic with no side effects. The LanceDB fix is also correct at the module level. The only concern is a pre-existing initPromise caching issue in MemoryDB.ensureInitialized that the LanceDB fix does not fully address, limiting the retry benefit in practice — but this is a non-blocking style observation.
  • extensions/memory-lancedb/index.ts — the MemoryDB.ensureInitialized method has a similar rejected-promise caching issue that was not addressed alongside loadLanceDB.

Comments Outside Diff (1)

  1. extensions/memory-lancedb/index.ts, line 72-82 (link)

    initPromise not reset on failure — retry not possible

    This PR correctly resets lancedbImportPromise on failure so loadLanceDB can be retried. However, ensureInitialized stores the result of doInitialize() in this.initPromise and never clears it on rejection. If doInitialize throws (e.g. because loadLanceDB threw on first call), this.initPromise remains a rejected Promise object — which is truthy — so every subsequent call to ensureInitialized immediately returns the same rejected promise without retrying:

    if (this.initPromise) {
      return this.initPromise;   // permanently returns the rejected promise
    }

    Since MemoryDB is instantiated once inside register() and reused for the lifetime of the plugin, a transient failure during first initialization permanently breaks all store, search, delete, and count operations for that instance, even after lancedbImportPromise has been successfully reset. Applying the same reset pattern here would make both caches consistent:

    private async ensureInitialized(): Promise<void> {
      if (this.table) {
        return;
      }
      if (this.initPromise) {
        return this.initPromise;
      }
    
      this.initPromise = this.doInitialize().catch((err) => {
        this.initPromise = null; // allow retry on next call
        throw err;
      });
      return this.initPromise;
    }

Last reviewed commit: 724274e

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 724274eec0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

gatewayUrl: v,
token: v.trim() === props.settings.gatewayUrl.trim() ? props.settings.token : "",
});
props.onSettingsChange({ ...props.settings, gatewayUrl: v });

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.

P1 Badge Clear token when gateway URL changes

Removing token reset from the WebSocket URL input means credentials are now silently carried from one gateway endpoint to another. In this UI flow, onSettingsChange updates gatewayUrl but keeps token, and connectGateway later sends host.settings.token to whatever host.settings.gatewayUrl is set to (ui/src/ui/app-gateway.ts), so changing the URL and clicking Connect can leak a token intended for gateway A to gateway B. This regresses the per-gateway token isolation behavior expected by existing navigation tests and should be handled by clearing/reconfirming the token on URL change instead of preserving it unconditionally.

Useful? React with 👍 / 👎.

@aisle-research-bot

aisle-research-bot Bot commented Mar 12, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Gateway token can be unintentionally reused and leaked when Gateway URL changes (token not cleared)

1. 🟠 Gateway token can be unintentionally reused and leaked when Gateway URL changes (token not cleared)

Property Value
Severity High
CWE CWE-359
Location ui/src/ui/views/overview.ts:202-207

Description

The Overview page’s Gateway URL input no longer clears the stored gateway auth token when the URL changes.

Security impact:

  • Credential leakage / confused deputy: a user can paste/type a new (possibly attacker-controlled) gatewayUrl while the old settings.token remains set; when the user clicks Connect, the UI will initiate a WebSocket connection to the new URL and send the token in the connect auth payload.
  • Token persistence across endpoints: saveSettings() persists the token scoped to gatewayUrl in sessionStorage. Keeping the token unchanged while changing gatewayUrl will store the same token under the new gateway’s key as well, increasing the chance of accidental reuse/leak across different gateways.

Vulnerable change:

// ui/src/ui/views/overview.ts
@​input=${(e: Event) => {
  const v = (e.target as HTMLInputElement).value;
  props.onSettingsChange({ ...props.settings, gatewayUrl: v });
}}

Data flow (why this leaks):

  • Input: user-controlled gatewayUrl via Overview input.
  • State: props.settings.token remains populated after URL change.
  • Sink: connectGateway() constructs GatewayBrowserClient({ url: settings.gatewayUrl, token: settings.token }), and GatewayBrowserClient sends auth.token over the WebSocket during the connect request.

Previously, the UI cleared the token when the trimmed gateway URL changed, which acted as a safeguard against cross-endpoint token reuse.

Recommendation

Reintroduce a safety barrier to prevent cross-endpoint token reuse.

Minimum fix (restore previous behavior):

@​input=${(e: Event) => {
  const v = (e.target as HTMLInputElement).value;
  props.onSettingsChange({
    ...props.settings,
    gatewayUrl: v,
    token: v.trim() === props.settings.gatewayUrl.trim() ? props.settings.token : "",
  });
}}

Stronger mitigations (preferred):

  • Scope tokens per gateway and never auto-carry them: when gatewayUrl changes, set token to "" or to the stored token for that new gateway (if any), instead of reusing the current one.
  • Require explicit confirmation before connecting to a different host when a token is present (similar to the existing pendingGatewayUrl confirmation flow used for URL-provided gateway changes).
  • Validate/limit gatewayUrl (e.g., restrict to same-origin / localhost / allowlisted hosts) when feasible.

These changes reduce the risk of leaking a privileged bearer token to an unintended endpoint.


Analyzed PR: #41718 at commit ec86573

Last updated on: 2026-03-12T19:34:48Z

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fbc624329e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

gatewayUrl: v,
token: v.trim() === props.settings.gatewayUrl.trim() ? props.settings.token : "",
});
props.onSettingsChange({ ...props.settings, gatewayUrl: v });

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.

P1 Badge Clear gateway token when endpoint changes

Preserving props.settings.token while the WebSocket URL is edited means the previously entered token is now reused for a different endpoint, and connectGateway will submit that token with the new URL on the next connect attempt (ui/src/ui/app-gateway.ts:201-203). This can leak credentials across gateways (for example, switching from gateway A to gateway B in Overview and clicking Connect) and regresses the existing behavior contract covered by ui/src/ui/navigation.browser.test.ts:201-215 ("clears the current token when the gateway URL changes").

Useful? React with 👍 / 👎.

@zheliu2
zheliu2 force-pushed the zheliu/fix-ws-url-clears-token branch from fbc6243 to ec86573 Compare March 12, 2026 19:03

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec8657344e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

gatewayUrl: v,
token: v.trim() === props.settings.gatewayUrl.trim() ? props.settings.token : "",
});
props.onSettingsChange({ ...props.settings, gatewayUrl: v });

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.

P1 Badge Prevent copying token into new gateway URL scopes

Updating only gatewayUrl here keeps props.settings.token intact, and onSettingsChange persists that pair through saveSettings -> persistSessionToken(next.gatewayUrl, next.token) (ui/src/ui/storage.ts:203-209). Because this runs on every input event, typing a different URL now writes the existing token under each intermediate/new URL scope, so a token entered for gateway A is silently reused for gateway B (and then loaded for B on refresh). This breaks the per-gateway token isolation behavior covered by ui/src/ui/storage.node.test.ts:172-215 and can leak credentials across endpoints.

Useful? React with 👍 / 👎.

@zheliu2
zheliu2 force-pushed the zheliu/fix-ws-url-clears-token branch from ec86573 to a5873a0 Compare March 14, 2026 14:56
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 26, 2026
@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve.

Keep open. Current main still clears the Gateway Token when the Overview WebSocket URL input changes, so this PR's stated UI problem is not implemented on main. The PR also should not land as-is because preserving the current token while changing gatewayUrl can carry a gateway-scoped credential to a different endpoint and persist it under the edited URL scope. The unrelated memory-lancedb retry hunk is already covered more completely on current main.

Best possible solution:

Keep this PR open for maintainer rework or replacement in the #41545 fix cluster. The best path is to drop the already-superseded memory-lancedb hunk, then fix the Overview editing UX without breaking per-gateway credential isolation: clear or reload the token when the normalized endpoint actually changes, or require explicit confirmation before reusing a token across gateways. Add focused regression coverage for both in-progress URL editing ergonomics and cross-gateway token isolation, and coordinate with open PRs #41546 and #42001.

What I checked:

  • docs_token_scope: The Control UI docs say the dashboard keeps a token for the current browser tab session and selected gateway URL; that makes the PR's unconditional token preservation a credential-scope change, not only a UI convenience change. Public docs: docs/web/control-ui.md. (docs/web/control-ui.md:32, ef58307f843e)
  • current_main_still_clears_token_on_url_input: The Overview WebSocket URL input still updates gatewayUrl and clears token unless the typed trimmed value matches the previous settings URL. (ui/src/ui/views/overview.ts:266, ef58307f843e)
  • test_contract_expects_clear_on_gateway_change: The navigation browser test hydrates a token, changes the gateway URL input to another gateway, and asserts settings.token becomes empty. (ui/src/ui/navigation.browser.test.ts:562, ef58307f843e)
  • connect_sends_current_settings_token_to_current_url: connectGateway constructs GatewayBrowserClient with host.settings.gatewayUrl and host.settings.token, so a token preserved through URL editing would be submitted to the edited endpoint on Connect. (ui/src/ui/app-gateway.ts:414, ef58307f843e)
  • settings_changes_persist_gateway_scoped_tokens: applySettings saves every settings change, and persistSettings calls persistSessionToken(next.gatewayUrl, next.token), whose storage key is derived from the normalized gateway URL. (ui/src/ui/storage.ts:171, ef58307f843e)
  • url_import_flow_already_uses_confirmation_for_gateway_changes: The URL-provided gateway change path defers a changed gateway URL and token into pendingGatewayUrl/pendingGatewayToken, then confirmation applies the new URL with only the pending token, showing current main already has a safer cross-gateway change pattern. (ui/src/ui/app-settings.ts:215, ef58307f843e)

Likely related people:

  • Chris Zhang [email protected]: git blame, git shortlog, and git show on the central UI/storage/gateway/test and memory-lancedb files all point to grafted commit 081e4be in this checkout. This is the strongest local routing signal, though the shallow snapshot history limits original-feature provenance. (role: recent current-main snapshot maintainer; confidence: medium; commits: 081e4be11e63; files: ui/src/ui/views/overview.ts, ui/src/ui/navigation.browser.test.ts, ui/src/ui/app-gateway.ts)
  • Peter Steinberger [email protected]: The latest release tag v2026.4.26 points to commit be8c246 by Peter Steinberger, and that tag contains the same relevant UI/token and memory-lancedb surfaces. This is useful release-routing evidence, not precise authorship for the original behavior. (role: release snapshot maintainer; confidence: low; commits: be8c24633aaa; files: ui/src/ui/views/overview.ts, ui/src/ui/navigation.browser.test.ts, ui/src/ui/storage.ts)

Remaining risk / open question:

  • Landing the UI hunk as-is can reuse a token entered for one gateway endpoint against another edited gatewayUrl when the user clicks Connect.
  • Because settings changes are saved immediately, preserving the token while typing a different URL can persist the old token under intermediate or new gateway URL scopes in sessionStorage.
  • The PR mixes the UI credential-handling change with an unrelated memory-lancedb retry hunk that current main already covers, making review and landing harder than necessary.
  • The current checkout has shallow/grafted snapshot history, so owner provenance is less precise than a full upstream history search.

Codex review notes: model gpt-5.5, reasoning high; reviewed against ef58307f843e.

@openclaw-clownfish

Copy link
Copy Markdown
Contributor

Thanks @zheliu2. I am closing this as superseded by #73923 for the #41545 Gateway Token fix. Both PRs cover the same Overview WebSocket URL edit bug, and #73923 is now the canonical Clownfish path: #73923.

That path keeps the useful UI behavior while preserving the gateway-token scope; the unrelated memory-lancedb retry hunk here is already covered on current main per the hydrated review. Your source PR remains credited in this closeout and audit trail. If this still carries unique work not covered by #73923 or main, please reply and we can reopen or split it back out.

eleboucher pushed a commit to eleboucher/homelab that referenced this pull request Jun 16, 2026
…26.6.8) (#1144)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.6.6` → `2026.6.8` |

---

### Release Notes

<details>
<summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary>

### [`v2026.6.8`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#202668)

[Compare Source](openclaw/openclaw@v2026.6.6...v2026.6.8)

##### Highlights

- Telegram and WhatsApp channel delivery are richer and less brittle: Telegram can send structured rich text with tables, lists, expandable blockquotes, prompt-preserving CLI backend delivery, retired native draft migration, and safer rich-media boundaries, while WhatsApp now honors configured ACP bindings. ([#&#8203;92679](openclaw/openclaw#92679), [#&#8203;84082](openclaw/openclaw#84082), [#&#8203;89421](openclaw/openclaw#89421), [#&#8203;92513](openclaw/openclaw#92513)) Thanks [@&#8203;obviyus](https://github.com/obviyus), [@&#8203;jzakirov](https://github.com/jzakirov), [@&#8203;spacegeologist](https://github.com/spacegeologist), and [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle).
- Agent and Gateway recovery is sharper across account-scoped DM sends, generated media completions, restart shutdown aborts, yielded subagent pauses, yielded cron media, heartbeat dedupe, session identity prompts, and unknown OpenAI agent selector rejection. ([#&#8203;92788](openclaw/openclaw#92788), [#&#8203;91246](openclaw/openclaw#91246), [#&#8203;91357](openclaw/openclaw#91357), [#&#8203;92631](openclaw/openclaw#92631), [#&#8203;92146](openclaw/openclaw#92146), [#&#8203;91287](openclaw/openclaw#91287), [#&#8203;92468](openclaw/openclaw#92468), [#&#8203;92510](openclaw/openclaw#92510)) Thanks [@&#8203;yetval](https://github.com/yetval), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), [@&#8203;ooiuuii](https://github.com/ooiuuii), [@&#8203;openperf](https://github.com/openperf), [@&#8203;IWhatsskill](https://github.com/IWhatsskill), [@&#8203;ZengWen-DT](https://github.com/ZengWen-DT), and [@&#8203;zhangguiping-xydt](https://github.com/zhangguiping-xydt).
- Provider/model handling expands and tightens with GLM-5.2, Claude Haiku 4.5 catalog rows, OpenRouter and Google Vertex provider-prefix normalization, managed SecretRef auth, bounded model browse discovery, storeless OpenAI Responses replay gating, and Claude 4.5 Copilot tool-streaming safety. ([#&#8203;92796](openclaw/openclaw#92796), [#&#8203;90116](openclaw/openclaw#90116), [#&#8203;92627](openclaw/openclaw#92627), [#&#8203;91218](openclaw/openclaw#91218), [#&#8203;90686](openclaw/openclaw#90686), [#&#8203;92247](openclaw/openclaw#92247), [#&#8203;90706](openclaw/openclaw#90706), [#&#8203;75393](openclaw/openclaw#75393)) Thanks [@&#8203;arkyu2077](https://github.com/arkyu2077), [@&#8203;liuhao1024](https://github.com/liuhao1024), [@&#8203;bymle](https://github.com/bymle), [@&#8203;rohitjavvadi](https://github.com/rohitjavvadi), [@&#8203;samson910022](https://github.com/samson910022), [@&#8203;snowzlm](https://github.com/snowzlm), and [@&#8203;Kailigithub](https://github.com/Kailigithub).
- `/usage` and reply payload hooks now have a native full footer renderer, default template, fixed-decimal formatting, credential-aware limits, better partial-count handling, and warnings for broken templates instead of silent bad output. ([#&#8203;92657](openclaw/openclaw#92657), [#&#8203;89835](openclaw/openclaw#89835), [#&#8203;89629](openclaw/openclaw#89629)) Thanks [@&#8203;Marvinthebored](https://github.com/Marvinthebored).
- UI and mobile flows are steadier: workspace files can collapse and start collapsed, WebChat backscroll survives streaming, the sidebar session picker remains interactive above the desktop workbench, reset soft args survive UI dispatch, stale dashboard session parent lineage is preserved, and iOS reconnects stale foreground gateways. ([#&#8203;92779](openclaw/openclaw#92779), [#&#8203;92622](openclaw/openclaw#92622), [#&#8203;92705](openclaw/openclaw#92705), [#&#8203;91353](openclaw/openclaw#91353), [#&#8203;90658](openclaw/openclaw#90658), [#&#8203;92552](openclaw/openclaw#92552)) Thanks [@&#8203;shakkernerd](https://github.com/shakkernerd), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), [@&#8203;NianJiuZst](https://github.com/NianJiuZst), [@&#8203;zhouhe-xydt](https://github.com/zhouhe-xydt), [@&#8203;luoyanglang](https://github.com/luoyanglang), and [@&#8203;Solvely-Colin](https://github.com/Solvely-Colin).
- Memory, state, and diagnostics recover cleaner: oversized OpenAI embedding batches split before 431s, QMD memory search stays available in transient mode, SQLite avoids WAL on NFS state volumes, stuck-session recovery scheduling no longer resets warning backoff, and Infinity chunk limits stay genuinely unbounded. ([#&#8203;92650](openclaw/openclaw#92650), [#&#8203;92618](openclaw/openclaw#92618), [#&#8203;92639](openclaw/openclaw#92639), [#&#8203;91247](openclaw/openclaw#91247), [#&#8203;92752](openclaw/openclaw#92752), [#&#8203;92735](openclaw/openclaw#92735)) Thanks [@&#8203;mushuiyu886](https://github.com/mushuiyu886), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), [@&#8203;849261680](https://github.com/849261680), [@&#8203;gnanam1990](https://github.com/gnanam1990), and [@&#8203;yhterrance](https://github.com/yhterrance).

##### Changes

- Providers/models: add GLM-5.2 support and Claude Haiku 4.5 catalog entries while keeping provider-qualified model IDs normalized across OpenRouter and Google Vertex paths. ([#&#8203;92796](openclaw/openclaw#92796), [#&#8203;90116](openclaw/openclaw#90116), [#&#8203;92627](openclaw/openclaw#92627), [#&#8203;91218](openclaw/openclaw#91218)) Thanks [@&#8203;arkyu2077](https://github.com/arkyu2077), [@&#8203;liuhao1024](https://github.com/liuhao1024), and [@&#8203;bymle](https://github.com/bymle).
- Channel plugins: ship Telegram rich-message delivery and WhatsApp ACP binding support, including rich prompt handoff to CLI backends and transport fixtures for richer drafts. ([#&#8203;92679](openclaw/openclaw#92679), [#&#8203;92513](openclaw/openclaw#92513)) Thanks [@&#8203;obviyus](https://github.com/obviyus) and [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle).
- Agent commands: support `/btw` in CLI-backed sessions and keep CLI usage-error exits classified as usage failures instead of successful runs. ([#&#8203;92669](openclaw/openclaw#92669), [#&#8203;92162](openclaw/openclaw#92162)) Thanks [@&#8203;joshavant](https://github.com/joshavant) and [@&#8203;Pandah97](https://github.com/Pandah97).
- Usage hooks: add built-in full footer rendering, default footer templates, per-turn usage state, credential-aware limits, and fixed-decimal formatting for usage-bar templates. ([#&#8203;92657](openclaw/openclaw#92657), [#&#8203;89835](openclaw/openclaw#89835), [#&#8203;89629](openclaw/openclaw#89629)) Thanks [@&#8203;Marvinthebored](https://github.com/Marvinthebored).
- Docs and operator guidance: document node config examples, clarify before-install hook scope, correct agent default concurrency comments, refresh ZAI provider docs, and update channel/group docs for current Telegram and WhatsApp behavior. ([#&#8203;92677](openclaw/openclaw#92677), [#&#8203;92766](openclaw/openclaw#92766), [#&#8203;92695](openclaw/openclaw#92695)) Thanks [@&#8203;liuhao1024](https://github.com/liuhao1024), [@&#8203;sallyom](https://github.com/sallyom), and [@&#8203;ArielSmoliar](https://github.com/ArielSmoliar).

##### Fixes

- Onboarding/skills: show the Homebrew install recommendation only on macOS and Linux, so FreeBSD and other unsupported platforms no longer get a misleading brew prompt. Fixes [#&#8203;68893](openclaw/openclaw#68893); carries forward [#&#8203;68894](openclaw/openclaw#68894), [#&#8203;68910](openclaw/openclaw#68910), [#&#8203;68941](openclaw/openclaw#68941), [#&#8203;68943](openclaw/openclaw#68943), [#&#8203;69002](openclaw/openclaw#69002), and [#&#8203;69545](openclaw/openclaw#69545). Thanks [@&#8203;yurivict](https://github.com/yurivict), [@&#8203;Sanjays2402](https://github.com/Sanjays2402), [@&#8203;Eruditi](https://github.com/Eruditi), [@&#8203;JustInCache](https://github.com/JustInCache), [@&#8203;nnish16](https://github.com/nnish16), and [@&#8203;Mlightsnow](https://github.com/Mlightsnow).
- Channels and delivery: preserve account-scoped DM channel send policy, rich Telegram final replies, rich Telegram tables and lists, Telegram thread-create CLI remapping, Slack outbound `message_sent` hooks, contributed message-tool schema optionality, same-channel generated media completions, and channel chunking around surrogate pairs and Infinity limits. ([#&#8203;92788](openclaw/openclaw#92788), [#&#8203;92679](openclaw/openclaw#92679), [#&#8203;89421](openclaw/openclaw#89421), [#&#8203;89943](openclaw/openclaw#89943), [#&#8203;91137](openclaw/openclaw#91137), [#&#8203;91246](openclaw/openclaw#91246), [#&#8203;92735](openclaw/openclaw#92735)) Thanks [@&#8203;yetval](https://github.com/yetval), [@&#8203;obviyus](https://github.com/obviyus), [@&#8203;spacegeologist](https://github.com/spacegeologist), [@&#8203;rishitamrakar](https://github.com/rishitamrakar), [@&#8203;lundog](https://github.com/lundog), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), and [@&#8203;yhterrance](https://github.com/yhterrance).
- Auto-reply/groups: keep ordinary group text replies on automatic final-reply delivery while allowing `message(action=send)` for files, images, and other attachments to the same group or topic. Carries forward [#&#8203;43276](openclaw/openclaw#43276); refs [#&#8203;48004](openclaw/openclaw#48004). Thanks [@&#8203;NayukiChiba](https://github.com/NayukiChiba) and [@&#8203;ShakaRover](https://github.com/ShakaRover).
- Auto-reply/skills: preserve multiline payloads for `/skill` and direct skill slash commands while keeping command-head normalization for aliases, colon syntax, and bot mentions. Fixes [#&#8203;79155](openclaw/openclaw#79155); carries forward [#&#8203;81305](openclaw/openclaw#81305). Thanks [@&#8203;web3blind](https://github.com/web3blind).
- iMessage: normalize leading NUL sent-message echo prefixes while preserving interior NUL bytes and the leading attributedBody marker handling from [#&#8203;73942](openclaw/openclaw#73942). Carries forward [#&#8203;63581](openclaw/openclaw#63581). Thanks [@&#8203;drvoss](https://github.com/drvoss).
- Discord: give generated auto-thread titles a 60-second timeout and 4,096-token reasoning-model output budget, clamped to the selected model output cap. ([#&#8203;64734](openclaw/openclaw#64734)) Thanks [@&#8203;hanamizuki](https://github.com/hanamizuki).
- Agent, cron, and Gateway runtime: mark active main sessions before restart shutdown aborts, pause yielded subagent runs whose terminal also signals abort, preserve yielded media completions, de-duplicate main-session heartbeat events, expose session identity in runtime prompts, reject unknown OpenAI agent selectors, keep generated media completions and slash-command block replies in WebChat, preserve fresh post-compaction usage while clearing stale usage snapshots, and require admin privileges for HTTP session/model override surfaces. ([#&#8203;91357](openclaw/openclaw#91357), [#&#8203;92631](openclaw/openclaw#92631), [#&#8203;92146](openclaw/openclaw#92146), [#&#8203;91287](openclaw/openclaw#91287), [#&#8203;92468](openclaw/openclaw#92468), [#&#8203;92510](openclaw/openclaw#92510), [#&#8203;91246](openclaw/openclaw#91246), [#&#8203;50795](openclaw/openclaw#50795), [#&#8203;50845](openclaw/openclaw#50845), [#&#8203;82874](openclaw/openclaw#82874), [#&#8203;92651](openclaw/openclaw#92651), [#&#8203;92646](openclaw/openclaw#92646)) Thanks [@&#8203;ooiuuii](https://github.com/ooiuuii), [@&#8203;openperf](https://github.com/openperf), [@&#8203;IWhatsskill](https://github.com/IWhatsskill), [@&#8203;ZengWen-DT](https://github.com/ZengWen-DT), [@&#8203;zhangguiping-xydt](https://github.com/zhangguiping-xydt), [@&#8203;Hollychou924](https://github.com/Hollychou924), [@&#8203;leno23](https://github.com/leno23), and [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle).
- Agents/exec: default empty-success background completion notices on only for real chat channels, preserving explicit opt-outs and keeping generic providers silent while carrying forward the narrow UX intent from [#&#8203;39726](openclaw/openclaw#39726) and [#&#8203;46926](openclaw/openclaw#46926). Thanks [@&#8203;Sapientropic](https://github.com/Sapientropic) and [@&#8203;wenkang-xie](https://github.com/wenkang-xie).
- Providers and model replay: preserve storeless OpenAI Responses replay compatibility, avoid eager tool streaming for Claude 4.5 in Copilot, honor profile auth for SecretRef model entries, bound model browsing, strip provider prefixes where runtimes need bare IDs, and surface nested embedding fetch failures. ([#&#8203;90706](openclaw/openclaw#90706), [#&#8203;75393](openclaw/openclaw#75393), [#&#8203;90686](openclaw/openclaw#90686), [#&#8203;92247](openclaw/openclaw#92247), [#&#8203;92627](openclaw/openclaw#92627), [#&#8203;91218](openclaw/openclaw#91218), [#&#8203;92628](openclaw/openclaw#92628)) Thanks [@&#8203;snowzlm](https://github.com/snowzlm), [@&#8203;Kailigithub](https://github.com/Kailigithub), [@&#8203;rohitjavvadi](https://github.com/rohitjavvadi), [@&#8203;samson910022](https://github.com/samson910022), [@&#8203;liuhao1024](https://github.com/liuhao1024), [@&#8203;bymle](https://github.com/bymle), and [@&#8203;mushuiyu886](https://github.com/mushuiyu886).
- Memory, state, diagnostics, and config: split header-too-large embedding batches, keep QMD memory search enabled in transient mode, avoid SQLite WAL on NFS volumes, preserve recovery scheduling outside stuck-session warning backoff, and keep shell environment fallbacks contained in config write tests. ([#&#8203;92650](openclaw/openclaw#92650), [#&#8203;92618](openclaw/openclaw#92618), [#&#8203;92639](openclaw/openclaw#92639), [#&#8203;91247](openclaw/openclaw#91247), [#&#8203;92752](openclaw/openclaw#92752)) Thanks [@&#8203;mushuiyu886](https://github.com/mushuiyu886), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), [@&#8203;849261680](https://github.com/849261680), and [@&#8203;gnanam1990](https://github.com/gnanam1990).
- Workspace setup state: store setup completion outside the workspace dot directory using an OpenClaw-named root file, migrate valid legacy state forward, and avoid clobbering generic root `workspace-state.json` files for TigerFS-style dot-path compatibility. This Clownfish replacement carries forward the focused [#&#8203;53326](openclaw/openclaw#53326) fix idea because the original branch was closed and uneditable. ([#&#8203;53326](openclaw/openclaw#53326), [#&#8203;44783](openclaw/openclaw#44783), [#&#8203;39446](openclaw/openclaw#39446)) Thanks [@&#8203;1qh](https://github.com/1qh).
- UI/mobile/TUI: preserve dashboard session parent lineage, WebChat backscroll, reset soft command args, sidebar session picker interactivity, collapsed workspace files, resolved `/model` confirmation refs, and stale foreground iOS Gateway reconnects. ([#&#8203;90658](openclaw/openclaw#90658), [#&#8203;92622](openclaw/openclaw#92622), [#&#8203;91353](openclaw/openclaw#91353), [#&#8203;92705](openclaw/openclaw#92705), [#&#8203;92779](openclaw/openclaw#92779), [#&#8203;92773](openclaw/openclaw#92773), [#&#8203;92552](openclaw/openclaw#92552)) Thanks [@&#8203;luoyanglang](https://github.com/luoyanglang), [@&#8203;TurboTheTurtle](https://github.com/TurboTheTurtle), [@&#8203;zhouhe-xydt](https://github.com/zhouhe-xydt), [@&#8203;NianJiuZst](https://github.com/NianJiuZst), [@&#8203;shakkernerd](https://github.com/shakkernerd), [@&#8203;NarahariRaghava](https://github.com/NarahariRaghava), and [@&#8203;Solvely-Colin](https://github.com/Solvely-Colin).
- TUI: reload the active session after external `/new` or `/reset` session-change events so stale transcript and stream state clear promptly. Fixes [#&#8203;38966](openclaw/openclaw#38966); carries forward [#&#8203;40472](openclaw/openclaw#40472). Thanks [@&#8203;yizhanzjz](https://github.com/yizhanzjz) and [@&#8203;wsyjh8](https://github.com/wsyjh8).
- Control UI: preserve Gateway Access tokens during same-normalized WebSocket URL edits and reload gateway-scoped tokens when switching endpoints. Fixes [#&#8203;41545](openclaw/openclaw#41545); repairs [#&#8203;42001](openclaw/openclaw#42001) with additional source PRs [#&#8203;41546](openclaw/openclaw#41546), [#&#8203;41552](openclaw/openclaw#41552), and [#&#8203;41718](openclaw/openclaw#41718). Thanks [@&#8203;wsyjh8](https://github.com/wsyjh8), [@&#8203;llagy0020](https://github.com/llagy0020), [@&#8203;llagy007](https://github.com/llagy007), [@&#8203;pingfanfan](https://github.com/pingfanfan), and [@&#8203;zheliu2](https://github.com/zheliu2).
- Gateway CLI: tolerate a single transient clean WebSocket close before `hello-ok` so one-shot RPC calls reconnect instead of failing noisily, while repeated clean pre-hello closes still surface. Carries forward source PRs [#&#8203;54475](openclaw/openclaw#54475) and [#&#8203;54774](openclaw/openclaw#54774); [#&#8203;85253](openclaw/openclaw#85253) covered adjacent connect assembly diagnostics. Thanks [@&#8203;ruanrrn](https://github.com/ruanrrn).
- Gateway/Linux: keep root-owned systemd user service lifecycle commands on root's user manager when a stale `SUDO_USER` remains in a root shell with root's user bus environment. Fixes [#&#8203;81410](openclaw/openclaw#81410). Thanks [@&#8203;Ericksza](https://github.com/Ericksza) and [@&#8203;ChuckClose-tech](https://github.com/ChuckClose-tech).
- Release and test reliability: extend slow Gateway/full-suite watchdogs, split local full-suite shards when throttled, stabilize plugin auth marker fixtures, avoid brittle provider-ref error text, and keep QA Lab bootstrap selection assertions aligned with flow-only scenarios. ([#&#8203;92652](openclaw/openclaw#92652))
- macOS Peekaboo bridge: update the embedded Peekaboo package to 3.5.2 and route bundled-skill CLI commands through the OpenClaw app bridge so they inherit its Screen Recording and Accessibility grants.
- Agent routing: route subagent RPC callbacks addressed to an agent-shaped `--to` target to the correct session key instead of falling back to the main session, so WeChat (and other channel) session-key callbacks reach the intended subagent session. ([#&#8203;90231](openclaw/openclaw#90231)) Thanks [@&#8203;zhangguiping-xydt](https://github.com/zhangguiping-xydt).
- Cron: preserve model, fallback, thinking, timeout, light-context, unsafe-content, and tool allow-list overrides on implicit text payloads by promoting them to agent turns, while explicit system events still prune those fields. Fixes [#&#8203;28905](openclaw/openclaw#28905); carries forward [#&#8203;64060](openclaw/openclaw#64060) and [#&#8203;73946](openclaw/openclaw#73946). Thanks [@&#8203;liaoandi](https://github.com/liaoandi).
- QQBot delivery: keep markdown table chunks self-contained across message boundaries by preserving table state across block deliveries, flushing unfinished table-row fragments as plain text, and detecting short pipe-terminated rows by column count so split rows are not sent as malformed markdown. ([#&#8203;92428](openclaw/openclaw#92428)) Thanks [@&#8203;sliverp](https://github.com/sliverp).

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/1144
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui extensions: memory-lancedb Extension: memory-lancedb size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Editing WebSocket URL clears Gateway Token in Overview

1 participant