thedotmack/claude-mem · warning
[ide-detection] Failed to read VS Code extensions directory:
Error message
[ide-detection] Failed to read VS Code extensions directory:
What it means
hasVscodeExtension() reads ~/.vscode/extensions and logs this warning if readdirSync throws, returning false so IDE detection degrades gracefully. It means the extensions directory exists but could not be read — detection of the VS Code extension is skipped.
Solutions
- Inspect `ls -la ~/.vscode/extensions` — fix it if it is a file or broken symlink.
- Correct directory permissions so the current user can read it.
- Exclude the directory from security software interference.
- Re-run IDE detection after repair; a false return only skips VS Code extension hints, other IDE detection continues.
Example fix
// before
if (!existsSync(extensionsDirectory)) return false;
// after (stat + isDirectory check avoids the exists-but-not-a-dir trap)
try {
if (!statSync(extensionsDirectory).isDirectory()) return false;
} catch { return false; } Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'fs';
function isReadableDirectory(p: string): boolean {
try { return statSync(p).isDirectory(); } catch { return false; }
}
// before readdir: if (!isReadableDirectory(extensionsDirectory)) return false; Type guard
function hasFsError(e: unknown): e is NodeJS.ErrnoException {
return e instanceof Error && 'code' in e;
} Try / catch
try {
const entries = readdirSync(extensionsDirectory);
return entries.some(e => e.toLowerCase().includes(fragment.toLowerCase()));
} catch (error: unknown) {
console.warn('[ide-detection] Failed to read VS Code extensions directory:', error instanceof Error ? error.message : String(error));
return false;
} Prevention
- Use statSync(...).isDirectory() instead of existsSync to catch file-vs-dir confusion.
- Check ~/.vscode/extensions permissions after security-tool or profile-sync changes.
- Handle ENOENT, EACCES, and ENOTDIR distinctly in detection utilities.
- Cache detection results to limit repeated reads of a flaky path.
When it happens
Trigger: readdirSync(extensionsDirectory) throws despite existsSync passing — e.g. the path exists but is a file, or permission/bit-flip issues between the existence check and the read (TOCTOU), or an I/O error.
Common situations: ~/.vscode/extensions is a broken symlink or plain file; permissions tightened by security software; directory removed between check and read; disk I/O errors; synced/roamed profiles with restricted ACLs.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- installPluginDependencies: no package.json at
- Unable to acquire Chroma writer lock at
- Unable to remove unreadable Chroma writer lock at
- [uninstall] Could not read
- [uninstall] Could not read
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/60ba046820cd353c.
Report an issue: GitHub.
Appendix: source
Thrown at src/npx-cli/commands/ide-detection.ts:40
execFileSync('which', [command], { stdio: 'ignore' });
}
return true;
} catch (error: unknown) {
if (process.env.DEBUG) {
console.error(`[ide-detection] ${command} not in PATH:`, error instanceof Error ? error.message : String(error));
}
return false;
}
}
function hasVscodeExtension(extensionNameFragment: string): boolean {
const extensionsDirectory = join(homedir(), '.vscode', 'extensions');
if (!existsSync(extensionsDirectory)) return false;
try {
const entries = readdirSync(extensionsDirectory);
return entries.some((entry) => entry.toLowerCase().includes(extensionNameFragment.toLowerCase()));
} catch (error: unknown) {
console.warn('[ide-detection] Failed to read VS Code extensions directory:', error instanceof Error ? error.message : String(error));
return false;
}
}
export function detectInstalledIDEs(): IDEInfo[] {
const home = homedir();
return [
{
id: 'claude-code',
label: 'Claude Code',
detected: isCommandInPath('claude'),
hint: 'recommended',
},
{
id: 'opencode',
label: 'OpenCode',
detected:View on GitHub (pinned to d8bc9755e7)