{"record":{"id":"60ba046820cd353c","repo":"thedotmack/claude-mem","slug":"ide-detection-failed-to-read-vs-code-extensions","errorCode":null,"errorMessage":"[ide-detection] Failed to read VS Code extensions directory:","messagePattern":"\\[ide-detection\\] Failed to read VS Code extensions directory:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/npx-cli/commands/ide-detection.ts","lineNumber":40,"sourceCode":"      execFileSync('which', [command], { stdio: 'ignore' });\n    }\n    return true;\n  } catch (error: unknown) {\n    if (process.env.DEBUG) {\n      console.error(`[ide-detection] ${command} not in PATH:`, error instanceof Error ? error.message : String(error));\n    }\n    return false;\n  }\n}\n\nfunction hasVscodeExtension(extensionNameFragment: string): boolean {\n  const extensionsDirectory = join(homedir(), '.vscode', 'extensions');\n  if (!existsSync(extensionsDirectory)) return false;\n  try {\n    const entries = readdirSync(extensionsDirectory);\n    return entries.some((entry) => entry.toLowerCase().includes(extensionNameFragment.toLowerCase()));\n  } catch (error: unknown) {\n    console.warn('[ide-detection] Failed to read VS Code extensions directory:', error instanceof Error ? error.message : String(error));\n    return false;\n  }\n}\n\nexport function detectInstalledIDEs(): IDEInfo[] {\n  const home = homedir();\n\n  return [\n    {\n      id: 'claude-code',\n      label: 'Claude Code',\n      detected: isCommandInPath('claude'),\n      hint: 'recommended',\n    },\n    {\n      id: 'opencode',\n      label: 'OpenCode',\n      detected:","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/npx-cli/commands/ide-detection.ts#L22-L58","documentation":"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.","triggerScenarios":"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.","commonSituations":"~/.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.","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."],"exampleFix":"// before\nif (!existsSync(extensionsDirectory)) return false;\n// after (stat + isDirectory check avoids the exists-but-not-a-dir trap)\ntry {\n  if (!statSync(extensionsDirectory).isDirectory()) return false;\n} catch { return false; }","handlingStrategy":"validation","validationCode":"import { statSync } from 'fs';\nfunction isReadableDirectory(p: string): boolean {\n  try { return statSync(p).isDirectory(); } catch { return false; }\n}\n// before readdir: if (!isReadableDirectory(extensionsDirectory)) return false;","typeGuard":"function hasFsError(e: unknown): e is NodeJS.ErrnoException {\n  return e instanceof Error && 'code' in e;\n}","tryCatchPattern":"try {\n  const entries = readdirSync(extensionsDirectory);\n  return entries.some(e => e.toLowerCase().includes(fragment.toLowerCase()));\n} catch (error: unknown) {\n  console.warn('[ide-detection] Failed to read VS Code extensions directory:', error instanceof Error ? error.message : String(error));\n  return false;\n}","preventionTips":["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."],"tags":["filesystem","permissions","vscode","ide-detection"],"backgroundTag":"file-read-failed","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}