MoonshotAI / MoonshotAI/kimi-code
Remote Control on iOS Safari: session page enters a crash–reload loop seconds after connecting (iPhone 12, iOS 18.5)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Summary
After starting kimi web --remote-control on Windows and logging in on an iPhone 12 (iOS 18.5) via the QR code, the session page renders for a few seconds and then Safari shows "A problem repeatedly occurred" (the page entered a crash–reload loop). A manual refresh sometimes brings the page back for a few seconds before it dies again. The same URL in a desktop browser is completely stable.
Reporter's original description (Chinese):
windows启动kimi rc之后,iphone扫码登录之后跳转到这里了。一会儿能刷新出来,但刷新出来之后一小会儿又跳到这个界面。
Evidence
- CLI stderr shows a strict 1:1 alternation of
Remote device connected/Remote device disconnected. Each pair is one WS stream (open_stream → close). The web app normally holds 2+ concurrent WS connections (event channel + transcript channel), so only ever seeing one stream alive means the page dies before it can open the second — i.e. the renderer crashes within seconds of the first data arriving after each (re)load. - Same URL on desktop is fine → the daemon, the relay, and the bandwidth path are exonerated. The only difference is the iOS WebContent process resource ceiling (iPhone 12 = 4 GB RAM).
- The user once glimpsed Safari's generic crash banner ("a problem occurred, reloaded") at the top — confirming renderer crashes (not a content error, not a redirect loop).
- Reproduces with multiple different sessions, not just one large one.
- Client-side code (kimi-code-app, current main) contains no automatic reload/navigation logic that could produce this page: the token dialog only reloads after manual token entry, the device switcher only navigates on manual selection, URL sync is replaceState-only, WS drops only trigger reconnects. A daemon outage would show the in-app "connecting" splash, not the Safari error page.
Mechanism (confirmed)
A self-sustaining crash loop:
page loads → WS connects → daemon starts pushing session data → iOS kills the WebContent process (memory/energy) → WS drops (device disconnected) → Safari auto-reloads → WS reconnects (device connected) → crash again → after a few cycles Safari gives up with "A problem repeatedly occurred".
Candidate resource amplifiers (from code reading — the exact kill point still needs on-device profiling)
- Every (re)connect re-seeds the transcript channel:
sendTranscriptReset(kap-servertransport/ws/v1/sessionEventBroadcaster.ts,TRANSCRIPT_RESET_TAIL_TURNS = 0) sends an empty snapshot withhas_more_older: true, so the client immediately re-fetches transcript pages over REST and re-projects the session from scratch. Under rc this full re-fetch + re-projection happens on every flap. - Grouped session-list drain: the client drains all
GET /api/v2/sessions?view=by_workspacepages in the background on boot; the daemon recomputes grouping on every page with per-workspace serial alias resolution and no caching (kap-serverroutes/v2/sessions.ts— known N+1, ~3 s/page locally on machines with many workspaces). Over the relay + a home uplink this is minutes of continuous network/parse churn during exactly the first minute on the phone. - Assets through the uplink: HTML/JS are served
Cache-Control: no-cacheafter relay rewriting (remote-control.tsrewriteRemoteControlResponse), so every fresh load re-downloads the multi-MB bundle through the Windows machine's uplink. - daemon WS server uses
wsdefaults (perMessageDeflate: false); the browser↔relay leg is relay-side and not visible from this repo — worth checking its close codes/timing.
What would help
- Relay-side visibility into browser-stream close codes and timing for the affected device (the flapping is visible from the CLI side as connect/disconnect pairs).
- Safari Web Inspector profiling from a Mac to identify the precise kill point (memory vs. a WebKit crash).
- Consider a lighter mobile/rc boot path: bounded initial transcript window, pausing the grouped drain on metered/mobile connections, and caching rewritten assets.
Environment
- daemon:
kimi web --remote-control(experimental) on Windows 11 - relay: code-rc.kimi.com
- client: iPhone 12, iOS 18.5, Safari (on 5G)
- control: same URL in desktop browser — stable
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Safari Web Inspector profiling to distinguish a memory limit from a WebKit crash, and compare browser-stream close codes and timing on the relay. Trace reconnect behavior through transport/ws/v1/sessionEventBroadcaster.ts, routes/v2/sessions.ts, and remote-control.ts. Done means identifying the precise kill point and agreeing on a bounded mobile/remote-control mitigation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- mobile-dev, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100