必须同步清理本地和远程.vscode-server目录,否则因vscode 1.86+签名校验变严格,残留缓存会导致连接卡在“installing vs code server”或报cannot read property 'length' of undefined错误。

本地 .vscode-server 缓存必须同步清理
VSCode 1.86+ 对远程服务端二进制的签名校验变严格,本地残留的旧版 .vscode-server(Windows 在 %USERPROFILE%\.vscode-server,macOS/Linux 在 ~/.vscode-server)会与远程新版本不兼容,导致连接卡在 “Installing VS Code Server” 或报 Cannot read property 'length' of undefined。
- 不要只删
bin/current或某个子目录——整个.vscode-server目录都要删,否则元数据仍被复用 - Windows 用户注意:资源管理器可能锁定该目录,建议用 PowerShell 执行
Remove-Item -Recurse -Force $env:USERPROFILE\.vscode-server - macOS/Linux 可直接运行:
rm -rf ~/.vscode-server,但需确保 VSCode 已完全退出(不是“Keep Window”) - 删完后首次重连会重新下载 server,若国内直连超时,可在 VSCode 设置中为
remote.SSH.env添加:"VSCODE_AGENT_FOLDER": "https://npmmirror.com/mirrors/code-server"(路径需匹配你当前 VS Code 版本 commit ID)
Remote-SSH: Kill VS Code Server on Host 必须先执行
这个命令不只是“断开连接”,它会向远程主机发送指令,清理 ~/.vscode-server 下的活跃进程、socket 文件和临时锁。如果跳过这步直接删本地缓存,远程残留进程可能继续占用端口或文件句柄,重连时仍会失败。
- 快捷键:
Ctrl+Shift+P(Windows/Linux)或Cmd+Shift+P(macOS),输入并运行该命令 - 必须从列表中选择目标主机名(如
devenvc_w5ihni),不能只点右下角状态栏的“Disconnect” - 执行后等待几秒,再关闭 VSCode 窗口——关窗前不等它完成,远程进程可能没真正释放
为什么只清远程不碰本地还会失败
本地缓存不仅存 server 二进制,还包含扩展安装记录、端口转发配置、调试器协议适配器等上下文信息。当远程 .vscode-server 被手动 rm -rf 后重建,而本地仍拿着旧 session 的 handshake token,VSCode 就无法协商通道,表现为点击 Reconnect 按钮无响应或输出面板空白。
- 典型现象:
Remote-SSH: Connect to Host后 UI 卡住,但终端里ssh user@host完全正常 - 验证方式:打开 VSCode 输出面板(
Ctrl+Shift+U),切换到Remote-SSH日志,看是否有Failed to connect to the remote extension host或pipe failed - 根本原因不是网络或 SSH 配置错误,而是本地 client 和远程 server 的 runtime state 不一致
自动重连失效时,别信 remote.SSH.keepAlive
这个设置只管 VSCode 自身控制通道(比如设置同步、命令面板刷新),对终端、端口转发、文件监听等核心子通道完全无效。它也不发任何网络包,纯属 UI 层心跳。真正起作用的是 SSH 底层保活,必须靠 ~/.ssh/config 里的 ServerAliveInterval 和 ServerAliveCountMax。
-
remote.SSH.keepAlive改成 30 或 300 都没用,删掉或保持默认即可 - 要真稳定,必须在
~/.ssh/config对应 Host 块里加三行:ServerAliveInterval 60、ServerAliveCountMax 3、TCPKeepAlive yes - 仅客户端配了没用,远程服务器
/etc/ssh/sshd_config还得配ClientAliveInterval 60并sudo systemctl restart sshd
最易被忽略的一点:清理完本地和远程缓存后,必须彻底退出 VSCode 进程(macOS 上检查 Activity Monitor 里有没有 Code Helper 或 Code 进程残留),否则它会悄悄复用旧 socket 文件描述符,让下一次连接直接继承损坏状态。











