Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

/ide finds no workspaces under the CLI sandbox: kill(pid,0) EPERM misread as a dead process

未關閉 適合新手
#4,909 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
78/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
javascript
領域
cli

研究方向

從 app.js 中的 IDE 探索函式 kB() 開始,並將 hft() 與現有的 b_o() liveness helper 進行比較。追蹤 oft()/yft() socket 探測之前的鎖定檔篩選。完成的標準是 EPERM 不再捨棄運作中的 workspace,讓 /ide 能探索並連線至 sandbox 可存取的 IDE;驗證 sandbox 中的重現和除錯輸出。

由索引模型根據 Issue 內容生成。

描述

triage
Describe the bug

When Copilot CLI runs with its own sandbox enabled ("enabled": true), /ide always reports
"No active IDE workspaces found." — even though a compatible IDE is running, the lock file is
present and valid, and the IDE's MCP socket is reachable from inside the sandbox.

Running the exact same CLI version from the same directory outside the sandbox connects to the
IDE immediately.

Root cause

IDE discovery (kB() in app.js) filters lock files through a process-liveness check before it
ever probes the socket:

function hft(e){ try{ return process.kill(e,0), !0 } catch { return !1 } }
// ...
if(!hft(d.pid)){
  C.debug(`Skipping stale lock file (PID ${d.pid} not running): ${l}`);
  continue;
}

hft() swallows the error code and treats any throw as "process not running".

The bundled seatbelt profile (prebuilds/darwin-arm64/runtime.node) contains:

(allow signal (target same-sandbox))

The IDE process lives outside the CLI's sandbox, so it is not same-sandbox. process.kill(pid, 0)
therefore fails with EPERM, not ESRCH.

EPERM from kill(pid, 0) means "the process exists, but you are not permitted to signal it" —
i.e. the process is alive. It is the one error code that positively proves liveness. Treating it
as "dead" discards every lock file, and discovery returns zero entries before the socket probe
(oft() / yft()) is reached.

The CLI already has a second liveness helper elsewhere in the same bundle that handles this
correctly:

function b_o(e){
  try{ return process.kill(e,0), !0 }
  catch(t){ const n = t.code; return n === "ESRCH" ? !1 : n === "EPERM" }
}

So this is an inconsistency between two copies of the same check, not a design decision.

Evidence

Measured from inside the sandbox, against a live IDE lock file:

Step in kB() Result
read ~/.copilot/ide/*.lock OK — lock present, workspaceFolders matches cwd
hft(pid) → process.kill(pid, 0) throws EPERM (not ESRCH)
oft(socketPath, 250) socket probe connects in 0–2 ms — but never reached
curl --unix-socket <socketPath> http://localhost/ HTTP 404 (server alive and responding)

The debug lines this path emits when the sandbox is on (visible with debug logging enabled):

Skipping stale lock file (PID <pid> not running): <uuid>.lock
Discovered 0 IDE workspace entries

With the sandbox off, the same lock file yields (observed at default log level):

Connecting to IDE MCP server: IntelliJ IDEA (<workspace>)
Connected to IDE MCP server: IntelliJ IDEA
Affected version

GitHub Copilot CLI 1.0.86, macOS (darwin-arm64). Reproduced with JetBrains IDEs; the discovery code
is IDE-agnostic, so VS Code should be affected identically.

Steps to reproduce the behavior
  1. Open a project in a compatible IDE with the Copilot CLI integration, so that a lock file appears
    in ~/.copilot/ide/.
  2. Run copilot in that same directory with sandboxing enabled (I am using Anthropic SRT).
  3. Run /ide.
  4. Observe "No active IDE workspaces found."
  5. Re-run copilot with the sandbox disabled and run /ide again — the workspace is listed and
    connects.
Expected behavior

/ide should list and connect to the running IDE workspace regardless of whether the CLI is
sandboxed. Socket reachability — which already works under the sandbox — is the authoritative
liveness signal here.

Suggested fix

Treat EPERM as alive in hft(), matching the existing b_o() helper:

function hft(pid){
  try { process.kill(pid, 0); return true }
  catch (e) { return e.code === "EPERM" }   // EPERM => exists, not signalable
}

Two alternatives, either of which also resolves it:

  • Drop the PID pre-filter entirely and rely on the socket probe (yft/oft), which is a stronger
    liveness check and already sandbox-safe.
  • Widen the seatbelt profile to permit kill(pid, 0) against non-sandboxed PIDs — but the code-level
    fix is simpler and does not weaken the sandbox.
Notes

No user-facing sandbox setting can work around this: the (allow signal (target same-sandbox)) rule
is compiled into the runtime binary, and the network / filesystem / ignoreViolations config
keys do not cover signal delivery. The only current workaround is to run the CLI unsandboxed, which
is an unfortunate trade-off for a feature that otherwise works fine under the sandbox.

主要語言
Shell
星號
11.2k
分支
1.9k
平均合併
17 小時 6 分鐘
30 天內合併 PR
5

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

github/copilot-cli 的其他 Issue

查看 github/copilot-cli 的全部 Issue

相似的 Issue

更多 Shell/Bash Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。