Skip to content

fix: perch could not load its parser on Windows - #441

Merged
jbrown9513 merged 9 commits into
mainfrom
claude/windows-parser-dependency-56762a
Oct 29, 2026
Merged

jbrown9513 merged 9 commits into
mainfrom
claude/windows-parser-dependency-56762a

Conversation

@jbrown9513

@jbrown9513 jbrown9513 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Perch stopped before reading anything on Windows. The parser addon in @xberg-io/tree-sitter-language-pack@1.22.1 imports napi_create_external and napi_type_tag_object from node.dll, which Node.js does not ship, so Windows refused to load it with "The specified module could not be found" (xberg-io/tree-sitter-language-pack#208).

  • On Windows, perch copies the addon to the temp directory with that import renamed to node.exe, which exports both functions, and loads the copy. An addon that imports no node.dll loads as published, so the patch goes inert once upstream ships the fix (fix(node): Windows addon imported node.dll and failed to load xberg-io/tree-sitter-language-pack#213).
  • Every use of the pack goes through src/treesitter/pack.ts.
  • .perch/ was never gitignored on Windows: perch checked that the results directory was inside the repository with a / prefix, which a Windows path does not have.
  • CI builds perch, runs perch --version, and runs the parser, scan and CLI tests on Windows under Node 22 and 24.

Windows users update perch. Nothing else changes.

Closes #440

@perchcode-bot

perchcode-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Perch Scan: no issues in 200 methods at 0a11efe.

1 issue fixed since the last push.

See the scan

@perchcode-bot perchcode-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perch found 6 issues in code this pull request changed. See the scan

Comment thread src/treesitter/pack.ts
* Renames one DLL in a PE file's import table, in place, and says whether it found it. The new name must be no longer than the
* old, since the string is overwritten where it sits.
*/
export function renameImport(pe: Buffer, from: string, to: string): boolean {

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P1 Defect: off by one (99%)

Perch believes renameImport has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::renameImport. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

Comment thread src/treesitter/pack.ts
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';

type Pack = typeof import('@xberg-io/tree-sitter-language-pack');

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P1 Defect: off by one (89%)

Perch believes <top-level> has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::<top-level>. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

Comment thread src/treesitter/pack.ts
* to node.exe binds to the running Node.js, which is what every node-gyp addon does. The copy is loaded in place of the pack's
* index.js, which does nothing but load the addon and export it. A pack whose addon imports no node.dll loads as published.
*/
function load(): Pack {

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P1 Defect: off by one (87%)

Perch believes load has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::load. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

Comment thread src/treesitter/pack.ts
* to node.exe binds to the running Node.js, which is what every node-gyp addon does. The copy is loaded in place of the pack's
* index.js, which does nothing but load the addon and export it. A pack whose addon imports no node.dll loads as published.
*/
function load(): Pack {

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of a707bdd no longer reports this.

P1 Security: weak crypto (79%)

Perch believes load has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::load. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of a707bdd no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

Comment thread src/treesitter/pack.ts
import { tmpdir } from 'node:os';
import { dirname, join } from 'node:path';

type Pack = typeof import('@xberg-io/tree-sitter-language-pack');

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of a707bdd no longer reports this.

P1 Security: weak crypto (71%)

Perch believes <top-level> has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::<top-level>. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of a707bdd no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

Comment thread src/treesitter/pack.ts Outdated
const optional = header + 24;
const directories = optional + (pe.readUInt16LE(optional) === 0x20b ? 112 : 96);
const table = optional + pe.readUInt16LE(header + 20);
const offset = (rva: number): number | undefined => {

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P2 Defect: off by one (95%)

Perch believes renameImport.offset has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/treesitter/pack.ts::renameImport.offset. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

@perchcode-bot perchcode-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perch found an issue in code this pull request changed. See the scan

Comment thread src/store.js
@@ -244,9 +244,11 @@ export function openStore(out) {
},
/** Ignore generated results while allowing closures and the default rule directory to be committed. */
async exclude(root) {

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P2 Defect: off by one (68%)

Perch believes openStore.store.exclude has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check src/store.js::openStore.store.exclude. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

@perchcode-bot perchcode-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perch found an issue in code this pull request changed. See the scan

Comment thread test/helpers.js

/** A fresh repository on `main` with a committed tree, then checked out on a feature branch, since fix and refactor commit to the current branch. */
/** Windows will not remove a directory something still has open, and a test's repository can stay open a moment after the test ends. */
export const removeDir = dir => rm(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 });

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 7e0f121 no longer reports this.

P2 Defect: leak (63%)

Perch believes removeDir has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check test/helpers.js::removeDir. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 7e0f121 no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

@jbrown9513
jbrown9513 marked this pull request as ready for review October 29, 2026 21:14
The Windows build of the parser addon in @xberg-io/tree-sitter-language-pack
1.22.1 cannot load, and nothing in CI ran on Windows to notice.
The pack's Windows addon imports two N-API functions from node.dll, which
Node.js does not ship. On Windows perch now loads a copy of the addon with
that import renamed to node.exe, which exports them.
exclude compared the results directory against the root with a '/' prefix,
which a Windows path never has. The Windows CI job runs the parser tests;
the scan tests do not yet pass there.
Test cleanup retries removing a temp repository, since Windows refuses
while it is still open.
A file already at the temp path is checked byte for byte before it is
loaded, and a section's address maps to the file only inside its raw data.
@jbrown9513
jbrown9513 force-pushed the claude/windows-parser-dependency-56762a branch from facc7bf to 6c2f826 Compare October 29, 2026 21:54

@perchcode-bot perchcode-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perch found an issue in code this pull request changed. See the scan

Comment thread test/helpers.js

/** A fresh repository on `main` with a committed tree, then checked out on a feature branch, since fix and refactor commit to the current branch. */
/** Windows will not remove a directory something still has open, and a test's repository can stay open a moment after the test ends. */
export const removeDir = dir => rm(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 200 });

@perchcode-bot perchcode-bot Bot Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: the scan of 0a11efe no longer reports this.

P2 Defect: other defect (63%)

Perch believes removeDir has this problem. It is a probability, not a located defect: the cause may sit a few lines away.

Check a fix with perch check test/helpers.js::removeDir. See the scan

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scan of 0a11efe no longer reports this, so Perch marked it fixed. Resolve this thread when you are done with it. See the scan

@jbrown9513
jbrown9513 merged commit acebf2c into main Oct 29, 2026
8 checks passed
@jbrown9513
jbrown9513 deleted the claude/windows-parser-dependency-56762a branch October 29, 2026 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perch fails to start on Windows: parser addon imports node.dll

1 participant