fix: use pathToFileURL for plugin entry import to support Windows paths#84
fix: use pathToFileURL for plugin entry import to support Windows paths#84Nivesh353 wants to merge 1 commit into
Conversation
Node's ESM loader requires a file:// URL for absolute paths on Windows — a raw "D:\..." path is misread as a URL with protocol "d:", causing plugin entry points to fail to load with "Received protocol 'd:'". Wrapping the path with pathToFileURL() fixes this on Windows while remaining correct on POSIX. Reproduced and verified live on Windows before the fix (exact predicted error), and confirmed no regression on POSIX after.
shreyas-lyzr
left a comment
There was a problem hiding this comment.
One-line fix, correct approach.
The change swaps a raw filesystem path into pathToFileURL(entryPath).href before passing it to import(). This is exactly how Node's ESM loader expects absolute paths to be fed in — raw Windows paths (e.g. D:\foo\index.js) are parsed as having protocol d: and rejected, while file:///D:/foo/index.js works correctly. On POSIX the conversion is a no-op in terms of behavior, so there's no regression risk.
Code reading notes:
pathToFileURLis from theurlbuilt-in — no new dependencies introduced.- The change is properly scoped to the one call site that does a dynamic
import()on a user-provided path. - The comment added in-line explains the why clearly.
Security pass: no CVEs (url is a Node built-in), no secrets, no injection or authz gaps — entryPath is derived from join(pluginDir, manifest.entry) where pluginDir is controlled by the plugin loader, same trust boundary as before.
One gap worth noting: there is no test that exercises the loadPlugin path with a real entry file. The existing test suite covers the SDK surface but not this code path directly. Not blocking — a unit test for plugin entry loading would be a good follow-up, but the fix itself is safe and the manual verification described in the PR body is credible.
Problem
Plugin entry points (
entry:inplugin.yaml) failed to load on Windows.src/plugins.tspassed the raw filesystem path directly intoimport().Node's ESM loader requires
file://URLs for absolute paths on Windows —a raw path like
D:\...\index.jsgets misread as protocold:and rejected.Reproduced live, before the fix
Plugin "my-plugin": failed to load entry "index.js": ...
Received protocol 'd:'
Plugin silently failed to load while gitagent kept running otherwise.
Fix
Testing
npm run build / npm test — clean, all 27 tests pass.
Verified on POSIX (Mac): plugin still loads correctly, no regression.
Verified on Windows: reproduced the exact error before the fix, confirmed it's resolved after.
Refs #30 (Windows plugin-loading finding only).