Repository navigation
[Bug]: SSH remote app-server never becomes ready on slow hosts, and a stale socket breaks the connection permanently #545
Copy link
Copy link
Open
Labels
bugSomething isn't workingSomething isn't workingdesktopMiniMax Code desktop appMiniMax Code desktop appneeds-triageAwaiting maintainer assessmentAwaiting maintainer assessment
Description
Product or interface
Desktop app
Version
Desktop 3.1.6.193; remote CLI @minimax-ai/code 0.6.13 (installed by the app's remote installer)
Platform
Windows
OS version and architecture
Microsoft Windows 11 Pro 10.0.26300 x64 (client). Remote hosts: CentOS Stream 9 (kernel 5.14.0-658.el9.x86_64 and 5.14.0-80.el9.x86_64, xfs, 4 vCPU Xeon E5-2690 v2 / E5-2697 v2, 1.9 GiB RAM).
Issue area
Startup / install / update
Desktop log upload ID (optional)
No response
Steps to reproduce
- Add an SSH connection in Settings → Connections pointing at a Linux host (CentOS Stream 9, xfs, 4 vCPU, 1.9 GiB RAM).
- The remote CLI installer runs and completes successfully (
https://filecdn.minimax.chat/public/install.sh,@minimax-ai/code@0.6.13). - Connect. The CLI is discovered, but the remote app-server never becomes ready:
mcode app-server daemon bootstrap --auth-mode remote-oauth→App-server did not become ready at /root/.minimax/app-server-control/app-server.sock within 10000ms. - Measure the real startup time on the same host by running the server in the foreground:
mcode app-server --listen unix:///root/.minimax/app-server-control/app-server.sock --foreground
→ the socket only appears after ~16 s (local-runtime-v2 startup ≈ 5 s, plus ~11 s more). On a faster host (Debian 12, ext4, 16 vCPU) the same command takes ~3 s and succeeds. - Kill the remote app-server process (or let the OOM killer do it) and reconnect: the stale
app-server.sockfile is still on disk, so every new instance exits immediately and the connection stays broken indefinitely.
Observed across four remote hosts:
| remote host | CPU / RAM / FS | socket ready | connect result |
|---|---|---|---|
| CentOS 9 | 4 vCPU E5-2690 v2, 1.9 GiB, xfs | ~16 s | fails (10 s window) |
| CentOS 9 | 4 vCPU E5-2697 v2, 1.9 GiB, xfs | ~16 s | fails (10 s window) |
| Debian 12 | 16 vCPU, ext4 | ~3 s | works |
| CentOS 9 | 2 vCPU, 1.9 GiB, xfs | ~16 s | fails, then OOM-killed (no swap) |
Expected and actual behavior
Expected: the remote app-server should come up regardless of how slow the host is, and a crashed instance should not permanently break the connection.
Actual:
mcode app-server daemon start|bootstrapwaits a hardcoded 10 s for the socket and then kills the child process. On a host that needs ~16 s, it can never succeed. The window is not configurable, and the error message does not mention that the host may simply have been slow.- In daemon mode the child's stdout is discarded (
stdio: ['ignore', 'ignore', <stderr>]), so the actual failure reason is invisible. Only a foreground run reveals it — e.g.App-server control directory requires effective 0700 permissions; use a private directory on a filesystem supporting Unix permissions. - A leftover
app-server.sockis never cleaned up. After a crash/OOM kill the socket file survives; new instances abort withApp-server socket is already in useand exit, and the connection then fails forever withremote_mcode_start_faileduntil the file is deleted by hand on the remote host. - A running instance is not reused by
daemon bootstrapunlessapp-server.state.jsonalso carrieslauncherPath/releaseKey/packageName/prefix/registry; otherwise it fails withappServerProfileMismatch: App-server is running from another installation. Stop it before starting the dedicated package.The fields are written by one entry point but not by the other. - On the Desktop side all of the above collapses into one generic "temporarily unavailable" state with code
remote_mcode_start_failed; the remote state (stale socket, dead process, missing permissions) is never inspected, so the user gets no actionable hint.
Workarounds used on our side (for validation)
- Keep the remote app-server running as a systemd unit started with
app-server --foreground --listen unix://... --state-file ..., and remove the stale socket inExecStartPre. - Write the install identity fields (
launcherPath,releaseKey,packageName,prefix,registry) intoapp-server.state.jsonsodaemon bootstrapaccepts the running instance. - Cap the Node heap (
NODE_OPTIONS=--max-old-space-size=...) and add swap on small hosts.
With those in place the same hosts connect and daemon bootstrap returns status: ready.
Suggested direction
- Wait for the server's own readiness event instead of a fixed 10 s window (or make the timeout configurable).
- Clean up / reuse a stale socket and an already-running instance before spawning a new child.
- Keep the child's stdout (or mirror key errors to stderr) so the real reason is visible.
- Distinguish the failure modes in the error code:
too slow,stale socket,permission,oom.
Redacted error summary
# remote host: CentOS Stream 9 / xfs / 4 vCPU / 1.9 GiB RAM
$ mcode app-server daemon bootstrap --auth-mode remote-oauth
{"action":"bootstrap","error":{"code":"appServerDaemonCommandFailed","message":"App-server did not become ready at /root/.minimax/app-server-control/app-server.sock within 10000ms.\nApp-server stderr (/root/.minimax/app-server-control/app-server.stderr.log):\n[auth-lease-broker] ready protocol=1\nmcode-tools readiness category=ready buildEnv=prod region=cn version=0.0.6","recommendedAction":"inspectRemoteLogs"}}
# desktop side
[SshRuntime] connection failed: The remote MCode app-server failed to start.
[SshRecovery] {"hostId":"...","state":"action_required","phase":"stopped","code":"remote_mcode_start_failed","disposition":"action_required"}
# foreground run on the same host: the socket only appears at ~16 s
$ mcode app-server --listen unix:///root/.minimax/app-server-control/app-server.sock --foreground
[auth-lease-broker] ready protocol=1
mcode-tools readiness category=ready buildEnv=prod region=cn version=0.0.6
# ... app-server.sock appears at t=16s
# after the process is killed, the socket file survives and blocks every new instance
$ ls -l /root/.minimax/app-server-control/app-server.sock
srw------- 1 root root 0 ... app-server.sock # owned by no live process
# reusing a healthy instance is rejected unless the state file carries the install identity
$ mcode app-server daemon bootstrap --auth-mode remote-oauth
{"action":"bootstrap","error":{"code":"appServerProfileMismatch","message":"App-server is running from another installation. Stop it before starting the dedicated package.","recommendedAction":"stopRemoteDaemon"}}Screenshots
N/A (textual reproduction above).
Before submitting
- I have searched existing issues.
- I have included my version and removed sensitive information.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingdesktopMiniMax Code desktop appMiniMax Code desktop appneeds-triageAwaiting maintainer assessmentAwaiting maintainer assessment
Activity