fix: convert sync I/O to async in session discovery to prevent VS Code UI freeze#527
Merged
fix: convert sync I/O to async in session discovery to prevent VS Code UI freeze#527
Conversation
…S Code UI freeze All filesystem operations in getCopilotSessionFiles() and scanDirectoryForSessionFiles() were synchronous (fs.existsSync, fs.readdirSync, fs.statSync), blocking Node.js's event loop during startup. With many workspaces/sessions (300+ is common), this caused VS Code to become completely unresponsive — extensions could not load, git would not start, and the status bar was permanently stuck on 'Loading...'. Changes: - Add private pathExists() async helper using fs.promises.access() - Convert getCopilotSessionFiles() to use fs.promises.readdir/stat/access throughout (workspaceStorage, globalStorage, Copilot CLI, OpenCode, Crush scan loops) - Make scanDirectoryForSessionFiles() async (fs.promises.readdir/stat) - Replace inline fs.existsSync in log messages with deferred path checks - Copilot CLI subdirectory loop now uses fs.promises.stat directly (combining the existsSync + statSync into a single async stat call) These async I/O calls yield the event loop between operations, allowing VS Code's UI and other extensions to run during the filesystem scan. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two user reports of VS Code becoming completely unresponsive after installing the extension:
From the attached screenshot, the extension activates quickly but the status bar is permanently stuck at "AI Fluency: Loading..." while VS Code's UI is frozen (blank splash screen, no editor loaded).
Root Cause
getCopilotSessionFiles()insessionDiscovery.tsis declaredasyncbut performed all filesystem I/O synchronously usingfs.existsSync,fs.readdirSync, andfs.statSync. Since JavaScript is single-threaded, synchronous I/O blocks Node.js's entire event loop — including VS Code's UI rendering and all other extension activity.The scan touches:
workspaceStorage/<hash>/chatSessions/directories (one per workspace — can be 500+)globalStorage/github.copilot-chat/(recursive scan)~/.copilot/session-state/subdirectories (onestatSyncper session)With 300+ sessions across many workspaces, this froze VS Code for long enough to break Git and other extensions.
Fix
Converted all filesystem operations in
getCopilotSessionFiles()andscanDirectoryForSessionFiles()to async equivalents:private async pathExists(p)helper usingfs.promises.access()to replacefs.existsSync()fs.readdirSync()→await fs.promises.readdir()fs.statSync()→await fs.promises.stat()scanDirectoryForSessionFiles()async throughoutexistsSync + statSyncinto a singleawait fs.promises.stat()call (catches ENOENT instead)Async I/O yields the event loop between operations, allowing VS Code's UI and other extensions to remain responsive during the filesystem scan.
Closes #493