Summary
egr index <dir> --scip <path> always fails to match any document when the .scip file was produced by a Windows-run external indexer (tested with scip-dotnet index, .NET 10 solution, Windows 11), even when <dir> is exactly the root the indexer was run against — the error message is misleading because it blames <dir>, but the real cause is a path-separator mismatch.
Root cause
In ingestScipOverlay (cli bundle, readScipIndexOrThrow → comparison logic):
const docPaths = new Set(index.documents.map((d) => d.relativePath));
const scipFiles = codeFiles.filter((f) => docPaths.has(f.path))...
codeFiles comes from egr's own walkFiles(), which normalizes paths through toPosixPath(relative(root, full)) — always forward-slash, regardless of OS.
index.documents[].relativePath, however, is taken as-is from the .scip protobuf with no normalization. scip-dotnet (the officially-recommended indexer for C#, per egr's own error message: scip-dotnet index for C#) emits Windows-style backslash-separated relative paths when run on Windows, e.g. PortaliteEnterprise.Api\Controllers\Capi\SmsController.cs.
Since the comparison is exact-string Set.has(), "Foo\Bar.cs" !== "Foo/Bar.cs" and zero documents ever match — 0/N every time, on every Windows-generated .scip file — while the tool reports:
--scip: none of the N document path(s) in "<file>" (e.g. "Foo\Bar.cs") matched any source file under "<dir>".
SCIP document paths are relative to the project root the external indexer ... was run against — pass that same root as <dir>, then retry.
This message strongly implies the fix is to change <dir>, which is a dead end — <dir> was already correct; no <dir> value fixes a separator mismatch.
Repro
- Windows machine, .NET solution.
dotnet tool install --global scip-dotnet
scip-dotnet index MySolution.sln --output my.scip --working-directory src
egr index src --scip my.scip
- →
--scip: none of the 293 document path(s) ... matched any source file under "src" — even though <dir> is correct.
Confirmed workaround
Rewrite the .scip file's Document.relative_path string fields from \ to / before feeding it to egr index --scip. Since both bytes are single-byte ASCII, an exact-substring byte replacement (matching each real relative file path, not a blanket byte-swap) preserves all protobuf length prefixes, so no reserialization is needed. After patching, the overlay matched (275/293 and 252/279 documents respectively across two solutions/dirs in our repo) and egr callers <symbol> started resolving cross-file calls correctly (previously always empty on our C# codebase due to tree-sitter's lack of type info).
Suggested fix
Normalize d.relativePath (and/or f.path) with the same toPosixPath() used for codeFiles before building docPaths / doing the comparison — one line, no protobuf reserialization needed on egr's side since this only needs to happen in memory at comparison time:
const docPaths = new Set(index.documents.map((d) => toPosixPath(d.relativePath)));
Also worth improving the error message to mention path-separator mismatch as a possible cause (not just "wrong <dir>"), since as written it sends users down the wrong debugging path.
Environment
- egr 0.9.1, Node v24.13.0, win32-x64
- scip-dotnet 0.2.14
- Windows 11
Related to earlier C# parsing bugs we reported in #1 and #2 — this one is in the --scip overlay path introduced since 0.9.1, not the tree-sitter parser itself.
Summary
egr index <dir> --scip <path>always fails to match any document when the.scipfile was produced by a Windows-run external indexer (tested withscip-dotnet index, .NET 10 solution, Windows 11), even when<dir>is exactly the root the indexer was run against — the error message is misleading because it blames<dir>, but the real cause is a path-separator mismatch.Root cause
In
ingestScipOverlay(cli bundle,readScipIndexOrThrow→ comparison logic):codeFilescomes from egr's ownwalkFiles(), which normalizes paths throughtoPosixPath(relative(root, full))— always forward-slash, regardless of OS.index.documents[].relativePath, however, is taken as-is from the.scipprotobuf with no normalization.scip-dotnet(the officially-recommended indexer for C#, per egr's own error message:scip-dotnet index for C#) emits Windows-style backslash-separated relative paths when run on Windows, e.g.PortaliteEnterprise.Api\Controllers\Capi\SmsController.cs.Since the comparison is exact-string
Set.has(),"Foo\Bar.cs" !== "Foo/Bar.cs"and zero documents ever match — 0/N every time, on every Windows-generated.scipfile — while the tool reports:This message strongly implies the fix is to change
<dir>, which is a dead end —<dir>was already correct; no<dir>value fixes a separator mismatch.Repro
dotnet tool install --global scip-dotnetscip-dotnet index MySolution.sln --output my.scip --working-directory srcegr index src --scip my.scip--scip: none of the 293 document path(s) ... matched any source file under "src"— even though<dir>is correct.Confirmed workaround
Rewrite the
.scipfile'sDocument.relative_pathstring fields from\to/before feeding it toegr index --scip. Since both bytes are single-byte ASCII, an exact-substring byte replacement (matching each real relative file path, not a blanket byte-swap) preserves all protobuf length prefixes, so no reserialization is needed. After patching, the overlay matched (275/293 and 252/279 documents respectively across two solutions/dirs in our repo) andegr callers <symbol>started resolving cross-file calls correctly (previously always empty on our C# codebase due to tree-sitter's lack of type info).Suggested fix
Normalize
d.relativePath(and/orf.path) with the sametoPosixPath()used forcodeFilesbefore buildingdocPaths/ doing the comparison — one line, no protobuf reserialization needed on egr's side since this only needs to happen in memory at comparison time:Also worth improving the error message to mention path-separator mismatch as a possible cause (not just "wrong
<dir>"), since as written it sends users down the wrong debugging path.Environment
Related to earlier C# parsing bugs we reported in #1 and #2 — this one is in the
--scipoverlay path introduced since 0.9.1, not the tree-sitter parser itself.