Dot 能聊天,也显示电脑已连接,却反复提示:

The desktop could not prepare a task workspace

2026 年 10 月 22 日,在一台 Windows 10 LTSC 2021 电脑上排查这件事,先后遇到了网络超时、会话访问拒绝,以及 PowerShell 启动崩溃。最后一条线索最扎实:脱离 Dot,单独启动 Codex 附带的 pwsh.exe ,同样报出 Windows 未完整支持 CET 的致命错误。给 PowerShell 设置兼容例外后,用户反馈命令有效。

这篇记录保留当时的证据和修复边界:已经复现并绕过的是 PowerShell 启动故障;会话结束时,还没有一份完整的 Dot 任务创建、执行及文件落盘验收记录。

先分清“已连接”到底证明了什么

最初的日志很容易把人带偏。聊天消息返回 HTTP 200,本机执行器每分钟报告在线,但 hostId=durable 的 WebSocket 持续 open_timeout 。这三件事可以同时发生。

检查对象当时观察到的结果可以得出的结论
Dot 聊天消息HTTP 200,收到回复消息收发正常
本机执行器持续报告已连接执行器的连接在采样期间在线
durable 连接15 秒后超时这条云端连接没有建立成功
新任务提示工作区准备失败尚未进入可确认的正常执行状态

此前还出现过插件文件被占用的 EBUSY 和凭据过期的 401 ,但它们已经自动恢复。后来的失败窗口没有重现这两个错误,不能一直拿旧错误解释新问题。

网络确实坏过,但修通后任务仍然失败

对当时安装版本的客户端代码和进程连接进行核对后,发现 durable 目标是:

wss://codex-cloud-backend.chatgpt.com/

这条 Node WebSocket 连接没有使用当时配置的系统 HTTP 代理。应用尝试直连本机 DNS 返回的地址,停在 SynSent ;显式使用本地代理则能完成 TLS,收到 HTTP 403。

未登录探测的 403 只说明已经到达远端 HTTP 服务,不能证明带认证的 WebSocket 握手成功。当时通过独立加密 DNS 查询得到的结果与本机 DNS 不一致;临时指定那些地址后,直连 TLS 仍失败,因此只改 DNS 也不足以恢复连接。

开启 Mihomo TUN 后,目标变成 Fake-IP,但连接仍超时。Windows 的实际选路解释了原因:指向虚拟网关的默认路由处于 Dead 状态,Fake-IP 流量反而被交给物理网卡。

在 Windows PowerShell 中,可以针对重新解析出的目标检查选路:

$target = Resolve-DnsName codex-cloud-backend.chatgpt.com -Type A |
    Where-Object Type -eq A |
    Select-Object -First 1 -ExpandProperty IPAddress
Find-NetRoute -RemoteIPAddress $target

这次还发现 Mihomo 网卡被识别为 Public,而已有程序放行规则仅适用于 Private。改成 Private 后,超时仍在;临时放行测试也没有消除故障。真正让连接恢复的是针对当前目标 Fake-IP、直接进入 Mihomo 网卡的精确路由。11:04 的应用日志记录了:

hostId=durable
initialized=true
next=connected
connectionError=null
reconnectAttempt=0

该机器随后安装了自动保持网络类别和目标路由的计划任务,脚本位于 C:\ProgramData\CodexMihomoNetworkFix\Ensure-MihomoPrivate.ps1 。这是该机针对失效路由的修补,不能据此认为 Mihomo 的默认路由问题已经整体解决。其他机器应先确认实际选路,不要照抄当时的 Fake-IP。

会话访问拒绝也是线索,却不是最终定论

网络恢复后,日志中出现了另一种明确错误:

method=thread/read
error.code=-32003
error.message="thread access denied"
source=thread_hydration

其中包含当前 Dot 关联的主会话。客户端先取得关联列表,再读取会话补齐任务信息,因此读取失败可以解释 Orbit catalog task metadata could not be loaded 。

但这还不能直接解释所有“新任务工作区准备失败”。本地账号比对一致,只排除了明显的本地身份混用;服务端为什么拒绝会话,仍需对应请求链才能判断。继续把所有失败归到权限上,会漏掉任务启动所依赖的本地程序。

转折点:pwsh.exe 的 Unknown Hard Error

随后用户报告 pwsh.exe 弹出了 Unknown Hard Error 。Windows 应用事件中找到多次一致记录:

Source: .NET Runtime
Event ID: 1023
Application: pwsh.exe
.NET: 10.0.11
Exit code: 0x80131506

这个错误码本身还不能定位根因。关键是找到了具体程序,再做最小启动测试。出问题的文件是 Codex 缓存中的 PowerShell,而此前远程诊断使用的 Windows 自带 powershell.exe 一直能运行。

在目标 Windows 电脑的 PowerShell 中,测试当时的运行时路径:

$runtimePwsh = Join-Path $env:USERPROFILE `
    '.cache\codex-runtimes\codex-primary-runtime\dependencies\native\powershell\pwsh.exe'
& $runtimePwsh -NoLogo -NoProfile -Command '$PSVersionTable.PSVersion'

这是本次核实过的缓存位置,应用更新后需重新确认。测试还没有开始执行实际任务,就出现:

Fatal error.
Your Windows doesn't fully support CET.
Please install all available Windows updates.

当时环境是 Windows 10 Enterprise LTSC 2021、21H2、构建号 19044.1415 ,查询到的最新热修复日期停在 2021 年 12 月。附带 PowerShell 文件版本为 7.6.5.500 ,签名有效。

至此可以确认:PowerShell 启动崩溃能脱离 Dot 独立复现。若任务准备需要启动这份解释器,它就是一个实际阻碍;这比从聊天措辞推断内部故障更有说服力。

有效的兼容命令,以及它的代价

CET 提供硬件支持的控制流保护,影子栈是其中一项机制。微软说明 .NET 从 9 开始默认标记 CET 兼容,也给出了对特定应用退出硬件堆栈保护的兼容办法,见 微软 CET 兼容性说明。

本次用户在管理员 Windows PowerShell 中执行了:

Set-ProcessMitigation -Name pwsh.exe -Disable UserShadowStack,UserShadowStackStrictMode

随后反馈“命令有效果”。这进一步支持了 CET 兼容性方向,但记录没有量化性能变化,也没有确认完整导出任务的最终产物。

这条命令的几个实际含义需要一起理解:

  • 它修改的是 Windows 中持久保存的程序缓解策略,通常重启或重开应用后仍然保留,不需要每次运行。
  • 按 pwsh.exe 名称配置,可能同时影响其他安装目录里的 PowerShell 7;Windows 自带的 powershell.exe 名称不同。
  • 被匹配的程序少了 CET 影子栈这一层保护。这是兼容例外,并未修复旧系统本身。
  • 同名程序更新后通常仍会匹配;管理策略覆盖、手动恢复默认或重装系统可能改变设置。

微软的 Set-ProcessMitigation 文档说明了注册表程序策略的修改方式。执行前应记录已有策略;若只想限定一个安装位置,可以在 Windows 安全中心的“漏洞利用防护 → 程序设置”中选择确切文件路径,而不是把名称规则当作目录专属设置。

长期处理与验证顺序

长期方向是检查并补齐适用于这台 LTSC 的系统更新,再重新测试原来的 PowerShell。此次会话没有安装更新,也没有实际重启验证,不能指定某个 KB 为本机已经验证过的修复。

更新后,应撤销本次两项应用例外,再运行同一个最小启动测试。恢复时保留其他已有程序保护设置,不要为省事删除整个程序策略注册表项。图形界面可将对应影子栈选项恢复为使用系统默认,并核对结果。

完整验收应依次做:

  1. 原路径的 pwsh.exe 能输出版本并执行简单命令,不再生成相同 .NET 崩溃事件。
  2. 应用的 durable 连接完成初始化,本机执行器在线。
  3. Dot 实际创建一个小任务,执行成功,并检查预期文件确实落盘。
  4. 如果仍提示工作区准备失败,继续检查当前“Projectless task folder”是否存在、可写、是否为目录链接,以及同一时刻的任务日志。

一次排查可以同时发现几处真实故障。网络连接恢复、会话读取成功、解释器能启动和任务完成,各有自己的证据。把它们分别验收,才能知道已经修好了哪一段,以及下一步该查哪里。

排查来源

本文依据 B660 上 2026 年 10 月 22 日的诊断会话整理。需要回看当时的完整私有记录,可在保存该会话的电脑上运行:

codex resume 01a16158-1b35-7071-aad7-9dc2731fded6

公开文章省略了账号标识、内部会话关联及支持请求编号。文中的版本、时间与路由状态均指当次现场,不代表其他版本的客户端一定采用相同实现。