Fix nil pointer dereference in aliasResolver.GetSourceFile#2814
Fix nil pointer dereference in aliasResolver.GetSourceFile#2814
Conversation
Add nil check for the return value of host.GetSourceFile() before passing it to binder.BindSourceFile(). The host can return nil when the file doesn't exist in the current snapshot (e.g., file deleted between snapshots, or module resolution resolved to a non-existent path during editing). Also add nil guard in registry.go updateIndexes where the result of GetSourceFile is used without checking for nil. Fixes #1203 Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
andrewbranch
left a comment
There was a problem hiding this comment.
@copilot your justification is a house of cards standing on one false justification: that module resolution can succeed and then the file can not exist when reading it from the same host. While this process happens during snapshot building, the FS state should be consistent after the first read of a given path. When module resolution checks if the file exists, it actually reads its contents into disk and stores the file record (see snapshotFSBuilder.FileExists). So you can't explain this behavior as a race. Once module resolution succeeds, that path is locked into both the snapshotFSBuilder state as well as the snapshotFS produced from it after finalization.
You should match my explanation against the real code to make sure I'm not making a mistake, but I think there must be another explanation.
There's also a second possible scenario: module resolution resolved to a
.d.tsor other file that exists on disk but whose path normalization differs from whatSnapshotFS.GetFileexpects.
Don't just say something is a possibility without any effort to back it up.
Keep looking; you now have the same understanding as me of why it should work, but you haven't found a real hole.
…ourceFile call - Rewrite investigation notes with thorough analysis of VFS architecture, the sourceFS.FileExists two-stage check with cachedvfs fallback, symlink path mismatch theories, and dirty.SyncMap edge cases. - Fix additional nil-unsafe binder.BindSourceFile(file) call in registry.go:createAliasResolver (the nil filter at lines 1080-1082 handles nil entries but only after the crash). - Investigation is honest about incomplete understanding: the exact triggering condition is uncertain, but several plausible theories involving stale cachedvfs caches and path normalization are documented. Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com>
You're right — the race explanation doesn't hold because The most interesting path I found is the However, tracing the The symlink path mismatch theory is also interesting — module resolution's I also found and fixed an additional nil-unsafe I haven't been able to pinpoint the exact triggering condition — the investigation notes document what I've found and what remains uncertain. |
aliasResolver.GetSourceFilepasses the result ofhost.GetSourceFile()directly tobinder.BindSourceFile()without a nil check. Unlikecompiler.Program.GetSourceFile(which does a map lookup over pre-loaded files), the alias resolver loads files on-demand fromSnapshotFS, which returns nil when a file doesn't exist. This crashes the language server during auto-import resolution.The checker already handles nil from
GetSourceFileForResolvedModule(checker.go:14809), so returning nil is correct behavior.binder.BindSourceFileGetSourceFileresult inupdateIndexesbefore passing toextractFromFileGetSourceFileresult increateAliasResolverbefore callingbinder.BindSourceFile(the existing nil filter at lines 1080-1082 only runs after the crash)investigation-nil-sourcefile-aliasresolver.mdwith root cause analysis covering the VFS architecture,sourceFS.FileExiststwo-stage check withcachedvfsfallback, symlink/realpath path mismatch theories, anddirty.SyncMapedge cases. The exact triggering condition remains uncertain.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.