You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sdk: "./sdk" export throws at import time — native module resolved outside its own security boundary #4785
Package:@github/copilot Version affected: 1.0.11 Platform: darwin-arm64
Summary
package.json's "exports" map points the documented import path @github/copilot/sdk at sdk/index.js. That bundle's own require() wrapper enforces a same-directory security check — it resolves the requested module's real path, computes it relative to the bundle's own directory (sdk/), and throws if the relative path starts with .. (i.e. the target lives outside sdk/).
The native pty.node addon this bundle needs at import time lives in the package root's prebuilds/<platform>/ directory — one level outsidesdk/. So the check the bundle enforces on itself is violated by the bundle's own required dependency, and import "@github/copilot/sdk" (or any import of sdk/index.js, including by absolute path) throws before a CopilotClient can even be constructed.
Reproduction
// Fails on darwin-arm64, @github/copilot@1.0.11:import("/opt/homebrew/lib/node_modules/@github/copilot/sdk/index.js").then(m=>console.log("OK",Object.keys(m))).catch(e=>console.error("ERR",e.message));
The surfaced error is misleading: it reads as Cannot find module './prebuilds/<platform>/pty.node', which looks like an ordinary missing-file error. It is not — it's the last of six internal resolution attempts inside a try/catch loop, and it overwrites the real, earlier error: Requiring module outside of application is a security concern, thrown by the custom require() wrapper on the 5th attempt. Confirmed by instrumenting Module._resolveFilename directly.
Impact
Anyone following the package's own documented entry point (@github/copilot/sdk) for the CLI's JSON-RPC SDK hits this immediately — the import throws, not a runtime session error.
Workaround found
Importing the older copilot-sdk/index.js bundle directly by absolute path instead of the documented @github/copilot/sdk specifier works — it exposes the identical public API (CopilotClient, CopilotSession, defineTool, approveAll, SYSTEM_PROMPT_SECTIONS), uses a plain createRequire(import.meta.url) with no directory-boundary check, and is unaffected.
Suggested fix directions
Either place sdk/'s security check's allowed root one level higher (package root, not sdk/), or ship prebuilds/ (or a copy/symlink of the needed native module) inside sdk/ so the resolved path never crosses the boundary the check enforces.
Fix the swallowed-error behavior regardless: the security-check error should not be silently overwritten by a later, unrelated "module not found" from a subsequent resolution attempt in the same try/catch loop — it hides the real cause from anyone hitting this for the first time.
Thanks for the report. We've shipped fixes in this area since this was filed (most recently in Copilot CLI v1.0.89), and we believe this may now be resolved. Could you retest on the latest release (Copilot CLI v1.0.103) and let us know whether you still see it? If we don't hear back in a couple of weeks, we may close this issue — you can always reopen it.
Triaged as part of a Copilot SDK backlog review, with help from GitHub Copilot.
Activity
patniko commentedon Oct 26, 2026
Thanks for the report. We've shipped fixes in this area since this was filed (most recently in Copilot CLI v1.0.89), and we believe this may now be resolved. Could you retest on the latest release (Copilot CLI v1.0.103) and let us know whether you still see it? If we don't hear back in a couple of weeks, we may close this issue — you can always reopen it.
Triaged as part of a Copilot SDK backlog review, with help from GitHub Copilot.