Skip to content

🐛 fix(desktop): unbreak dev cold-start + restore UI language across reloads#15547

Merged
Innei merged 5 commits into
canaryfrom
fix/desktop-dev-vite-fetch-pool
Jun 8, 2026
Merged

🐛 fix(desktop): unbreak dev cold-start + restore UI language across reloads#15547
Innei merged 5 commits into
canaryfrom
fix/desktop-dev-vite-fetch-pool

Conversation

@Innei

@Innei Innei commented Jun 8, 2026

Copy link
Copy Markdown
Member

💻 Change Type

  • 🐛 fix

🔗 Related Issue

Fixes LOBE-10086

Two desktop dev-mode bugs that surface together when running with a non-en-US UI language. Both regress from recent main-process changes (#15304 and the ?lng= URL-injection pattern), and a fresh dev start with navigator.language=zh-CN hits both.

🔀 Description of Change

1. Cold-start renderer-resource burst exhausting the main-process net pool

#15304 unified dev under app://renderer/ and routes every Vite asset through the main process. On cold start (~2.5k modules transforming) plus a non-default UI language (each i18n namespace fans out to its own HTTP request, ~50 at once), the Chromium main-process net pool blew up with ERR_INSUFFICIENT_RESOURCES and the renderer stayed white.

Fix is a three-part combo (all three are necessary — see verification table):

  • ViteRendererFallbackglobalThis.fetch (Node undici) instead of Electron net.fetch. undici has a per-origin connection pool and queues excess work internally instead of failing with ERR_INSUFFICIENT_RESOURCES.
  • Pin Vite dev server to 127.0.0.1 (server.host + hmr.host). With Vite on ::1 only, undici's happy-eyeballs attempts dual-stack connects per request, which under bursts surfaces as ETIMEDOUT from internalConnectMultiple. Single-stack listen eliminates those wasted attempts.
  • Keep Semaphore(64) capping in-flight fetch calls. Even with undici, an unbounded burst of thousands of concurrent module fetches saturates the OS socket layer.

2. UI language reverting to OS locale on Cmd+R / webContents.reload

The renderer's <html lang> was computed from ?lng= (injected by the main process at loadURL time via storeManager.locale) with navigator.language as fallback. webContents.reload() reuses the prior URL without rebuilding it, so users who changed their language after launch got dropped back to the OS locale on every reload — exactly the white-screen-into-English experience the cold-start fix was already setting up.

Read the i18next localStorage cache (i18nextLng) first — that's the actual persisted user setting, written by the language switcher every time changeLanguage runs — then fall back to the URL param and navigator. Web isn't affected because cookies + SSR set <html lang> correctly there; app:// can't persist cookies.

🧪 How to Test

Cold-start bursts — locally verified with navigator.language=en-GB:

Variant ERR_INSUFFICIENT_RESOURCES ETIMEDOUT Vite 502 Renderer
pre-fix (net.fetch + Semaphore 64) many white ~11s
undici fetch alone 0 93 93 white
undici + v4 listen 0 276 276 white
undici + v4 + Semaphore(64) 0 0 0 ready

Reload language persistence — set language to Chinese in Settings, then navigate to app://renderer/ (no ?lng= query) to simulate a fresh reload that hasn't gone through main-process URL injection. After fix: htmlLang=zh-CN, body renders in Chinese.

RendererProtocolManager.test.ts updated to vi.stubGlobal('fetch', ...) — all 9 tests pass.

  • Tested locally
  • Added/updated tests
  • No tests needed

`ViteRendererFallback` now proxies via globalThis `fetch` (Node undici) instead
of Electron `net.fetch`, and Vite dev server is pinned to IPv4 listen. The
main-process Chromium `net` pool is small and surfaces `ERR_INSUFFICIENT_RESOURCES`
under cold-start module bursts + ~50 i18n namespace fan-out under non-en-US
locales. undici queues internally and avoids that pool entirely; v4 listen avoids
happy-eyeballs dual-stack connect storms. A Semaphore(64) still caps in-flight
fetches so the OS socket layer never gets buried.

Fixes LOBE-10086
@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lobehub Ready Ready Preview, Comment Jun 8, 2026 1:01pm

Request Review

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. platform:desktop Desktop client trigger:build-desktop Trigger Desktop build labels Jun 8, 2026

@sourcery-ai sourcery-ai 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.

Sorry @Innei, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.56%. Comparing base (235a16f) to head (e720766).
⚠️ Report is 1 commits behind head on canary.

Additional details and impacted files
@@             Coverage Diff             @@
##           canary   #15547       +/-   ##
===========================================
- Coverage   89.10%   70.56%   -18.54%     
===========================================
  Files         898     3308     +2410     
  Lines      108660   326763   +218103     
  Branches     9680    34664    +24984     
===========================================
+ Hits        96818   230580   +133762     
- Misses      11659    96000    +84341     
  Partials      183      183               
Flag Coverage Δ
app 61.33% <ø> (?)
database 92.22% <ø> (ø)
packages/agent-manager-runtime 49.69% <ø> (ø)
packages/agent-runtime 81.06% <ø> (ø)
packages/builtin-tool-lobe-agent 18.52% <ø> (ø)
packages/context-engine 84.12% <ø> (ø)
packages/conversation-flow 91.29% <ø> (ø)
packages/device-gateway-client 90.18% <ø> (ø)
packages/eval-dataset-parser 95.15% <ø> (ø)
packages/eval-rubric 76.11% <ø> (ø)
packages/fetch-sse 85.57% <ø> (ø)
packages/file-loaders 87.89% <ø> (ø)
packages/memory-user-memory 74.99% <ø> (ø)
packages/model-bank 99.99% <ø> (ø)
packages/model-runtime 84.22% <ø> (ø)
packages/prompts 72.51% <ø> (ø)
packages/python-interpreter 92.90% <ø> (ø)
packages/ssrf-safe-fetch 0.00% <ø> (ø)
packages/types 35.23% <ø> (ø)
packages/utils 84.98% <ø> (ø)
packages/web-crawler 88.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Store 68.37% <ø> (∅)
Services 54.86% <ø> (∅)
Server 71.46% <ø> (∅)
Libs 56.10% <ø> (∅)
Utils 81.93% <ø> (-18.07%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The renderer's `<html lang>` was being computed from `?lng=` (injected by the
main process at `loadURL` time) with `navigator.language` as fallback. On
`Cmd+R` the webContents reload reuses the prior URL without rebuilding it
against `storeManager.locale`, so users who changed their language after
launch got dropped back to the OS locale on every reload (white screen, then
English). Read the i18next localStorage cache first — that's the actual
persisted user setting written by the language switcher — and fall back to the
URL param + navigator as before.
@Innei Innei changed the title 🐛 fix(desktop): unbreak dev cold-start on non-default UI languages 🐛 fix(desktop): unbreak dev cold-start + restore UI language across reloads Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

🚀 Desktop App Build Completed!

Version: 0.0.0-nightly.pr15547.15511
Build Time: 2026-06-08T13:20:38.973Z

📦 Release Download · 📥 Actions Artifacts

Build Artifacts

Platform File Size
macOS (Apple Silicon) LobeHub-Nightly-0.0.0-nightly.pr15547.15511-arm64-mac.zip 147.63 MB
macOS (Apple Silicon) LobeHub-Nightly-0.0.0-nightly.pr15547.15511-arm64.dmg 140.44 MB
macOS (Intel) LobeHub-Nightly-0.0.0-nightly.pr15547.15511-mac.zip 156.24 MB
macOS (Intel) LobeHub-Nightly-0.0.0-nightly.pr15547.15511-x64.dmg 147.66 MB
Windows LobeHub-Nightly-0.0.0-nightly.pr15547.15511-setup.exe 134.74 MB
Linux LobeHub-Nightly-0.0.0-nightly.pr15547.15511.AppImage 165.26 MB

Warning

Note: This is a temporary build for testing purposes only.

@Innei Innei merged commit 9b19ebb into canary Jun 8, 2026
37 checks passed
@Innei Innei deleted the fix/desktop-dev-vite-fetch-pool branch June 8, 2026 13:21
arvinxx added a commit that referenced this pull request Jun 10, 2026
# 🚀 LobeHub Release (20260610)

**Release Date:** June 10, 2026  
**Since v2.2.2:** 131 merged PRs · 13 contributors

> This weekly release strengthens agent collaboration across cloud,
desktop, CLI, and workspace flows, with steadier runtime behavior and a
broader foundation for workspace-scoped data.

---

## ✨ Highlights

- **Agent execution across devices** — Unifies per-device working
directories, project skill discovery, and sub-agent suspend/resume
behavior across server, QStash, and device RPC flows. (#15543, #15566,
#15481, #15620, #15591)
- **Connector and sandbox platform** — Expands connector permissions,
custom OAuth MCP connector onboarding, sandbox provider support, and
user-uploaded file sync into cloud sandbox runs. (#15463, #15546,
#15184, #15550)
- **Desktop and CLI reliability** — Fixes desktop cold-start,
auto-update, Windows build, CLI skill discovery, and `lh connect` agent
dispatch paths. (#15547, #15525, #15527, #15562, #15632, #15634)
- **Pages and sharing** — Refreshes topic sharing, improves Page Editor
layout behavior, and routes Page Agent tool execution through the
server-side editor path. (#15581, #15556, #15588, #15023, #15610)
- **Model availability and provider updates** — Adds user-scoped LobeHub
model availability, Claude Fable 5, Qwen thinking preservation, and
MiniMax M3 updates. (#15590, #15639, #13494, #15376)

---

## 🏗️ Core Product & Architecture

### Agent Runtime & Heterogeneous Agents

- Improves sub-agent lifecycle handling, including async suspend/resume,
queue-mode QStash resume delivery, and blocking nested sub-agent calls.
(#15481, #15620, #15575)
- Stabilizes heterogeneous agent ingestion and streaming with raw stream
dumps, per-turn usage, image forwarding on regenerate, and
duplicate-text fixes. (#15602, #15577, #15592, #15585)
- Adds execution-device and working-directory controls across device
RPC, legacy defaults, and remote-spawned Claude Code sessions. (#15543,
#15566, #15591, #15572)
- Improves runtime diagnostics and compatibility, including Gemini
multimodal output capture, abort stream semantics, and trace quality
analysis. (#15535, #13677, #15508)

---

## 📱 Platforms, Integrations & UX

### Connectors, Sandbox & Tools

- Ships API-level connector tool permissions, custom OAuth MCP connector
onboarding, and connector-first runtime execution. (#15463, #15546)
- Adds sandbox provider support, cloud sandbox file sync, and safer
external URL file input handling with SSRF validation. (#15184, #15550,
#12657)
- Improves tool visibility and execution with pinned app-fixed tools,
ANSI output rendering, gateway-tunneled MCP calls, and automatic
headless tool runs. (#15509, #15516, #15469, #15492)

### Desktop, CLI & Web UX

- Restores desktop startup and reload behavior, preserves IPC error
causes, and keeps the tab bar new-tab action visible across routes.
(#15547, #15597, #15638)
- Fixes desktop update and build stability for browser quit guards,
macOS update signing, and Windows Visual Studio detection. (#15525,
#15527, #15562)
- Shows the plan-limit upgrade UI on desktop builds. (#15628)
- Adds the Agent Run delivery checker and fixes CLI device dispatch plus
skill list/search output. (#15489, #15634, #15632)
- Refreshes onboarding, auth source preservation, topic UI states,
referral/Fable campaign copy, and chat-input control bar behavior.
(#15629, #15544, #15573, #15614, #15616, #15617, #15622, #15643)

---

## 🔒 Security, Reliability & Rollout Notes

- External URL file input now includes SSRF validation for safer Google
file handling. (#12657)
- Database workspace-scope migrations are part of this release;
self-hosted operators should run the normal migration path before
serving the updated app. (#15446, #15465, #15468, #15472)
- The release branch was re-cut from `canary` and includes the latest
`main` release-version commit so `v2.2.2` is the verified compare base.

---

## 👥 Contributors

@ONLY-yours, @sxjeru, @hardy-one, @xujingli, @hezhijie0327, @Coooolfan,
@arvinxx, @tjx666, @Innei, @rivertwilight, @rdmclin2, @cy948,
@AmAzing129

**Full Changelog**:
v2.2.2...release/weekly-20260610-recut-3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform:desktop Desktop client size:M This PR changes 30-99 lines, ignoring generated files. trigger:build-desktop Trigger Desktop build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant