问题
Workflow sandbox 使用 vm.Script(...).runInContext(..., { timeout: 1000 }) 限制不让出 CPU 的用户代码,但这个限制只覆盖首次同步执行。只要 Workflow 先经过一次 await,后续 Promise continuation 就在该 runInContext 调用之外执行,可以无限占用 sandbox 子进程的 CPU,且不会产生 result/error IPC。
最小示例:
await Promise.resolve();
while (true) {}
更贴近真实使用的形式是:
await agent("inspect the repository");
while (true) {}
模型生成的聚合或重试逻辑一旦在 await 后误入死循环,Workflow 会一直保持 running,并持续占用一个 CPU 核,直到用户显式取消或 Session 关闭。
当前行为
在当前 main a15a0d88837f580187cbb02d7fcab91bff8f0d34、Node v24.19.0、macOS 上对同一 sandbox child 做受控复现:
| Workflow source |
1 秒后结果 |
while (true) {} |
收到 Error: Script execution timed out after 1000ms |
await Promise.resolve(); while (true) {} |
1.6 秒后仍无 result/error;子进程约占用 95% CPU,只能从父进程强制终止 |
相关实现:
extensions/workflows/sandbox-child.cjs 中 bootstrap 和初次 invoke 分别使用 runInContext(..., { timeout: 1000 })。
context.__workflowPromise 的后续 Promise continuation 由 V8 microtask 执行,不再受这两个同步 runInContext timeout 约束。
tests/extensions/workflows/sandbox.test.ts 目前只覆盖首个 await 之前的 while (true) {}。
预期行为
Workflow 在任意 await 前后进入不让出 CPU 的用户代码时,都应在有界时间内失败并给出明确错误,不能无限占用 sandbox 子进程。
这不要求给整个 Workflow 或 agent() 调用增加固定 wall-clock deadline。正常的长时间 agent 等待仍应被允许;需要约束的是 sandbox 中连续执行、无法响应 IPC 或取消的用户代码。
建议验收
去重
已检索开放和关闭的 issue/PR,关键词包括 workflow sandbox timeout、Script execution timed out、after await、infinite loop、vm.Script timeout、sandbox CPU,未发现覆盖该问题的条目。
问题
Workflow sandbox 使用
vm.Script(...).runInContext(..., { timeout: 1000 })限制不让出 CPU 的用户代码,但这个限制只覆盖首次同步执行。只要 Workflow 先经过一次await,后续 Promise continuation 就在该runInContext调用之外执行,可以无限占用 sandbox 子进程的 CPU,且不会产生 result/error IPC。最小示例:
更贴近真实使用的形式是:
模型生成的聚合或重试逻辑一旦在
await后误入死循环,Workflow 会一直保持 running,并持续占用一个 CPU 核,直到用户显式取消或 Session 关闭。当前行为
在当前
maina15a0d88837f580187cbb02d7fcab91bff8f0d34、Nodev24.19.0、macOS 上对同一 sandbox child 做受控复现:while (true) {}Error: Script execution timed out after 1000msawait Promise.resolve(); while (true) {}相关实现:
extensions/workflows/sandbox-child.cjs中 bootstrap 和初次 invoke 分别使用runInContext(..., { timeout: 1000 })。context.__workflowPromise的后续 Promise continuation 由 V8 microtask 执行,不再受这两个同步runInContexttimeout 约束。tests/extensions/workflows/sandbox.test.ts目前只覆盖首个await之前的while (true) {}。预期行为
Workflow 在任意
await前后进入不让出 CPU 的用户代码时,都应在有界时间内失败并给出明确错误,不能无限占用 sandbox 子进程。这不要求给整个 Workflow 或
agent()调用增加固定 wall-clock deadline。正常的长时间 agent 等待仍应被允许;需要约束的是 sandbox 中连续执行、无法响应 IPC 或取消的用户代码。建议验收
await Promise.resolve(); while (true) {}在有界时间内失败,而不是持续 running。await agent(...)返回后进入死循环也得到相同保护。agent()的 Workflow 不会因为固定总时长而被误杀。去重
已检索开放和关闭的 issue/PR,关键词包括
workflow sandbox timeout、Script execution timed out、after await、infinite loop、vm.Script timeout、sandbox CPU,未发现覆盖该问题的条目。