typescript-lsp plugin: semantic operations fail in Yarn 1 monorepos with hoisted dependencies

Resolved 💬 2 comments Opened Mar 9, 2026 by headtrip-cgn Closed Apr 7, 2026

Bug Description

The typescript-lsp@claude-plugins-official plugin's semantic LSP operations (findReferences, goToDefinition, hover, documentSymbol) return no results in a Yarn 1 workspaces monorepo with hoisted node_modules. Only workspaceSymbol (which uses text-based indexing) works correctly.

Environment

  • OS: Windows 10 Pro 10.0.19045
  • Claude Code model: claude-opus-4-6
  • Plugin: typescript-lsp@claude-plugins-official
  • Monorepo setup: Yarn 1 workspaces + Turborepo
  • TypeScript: 5.5.4
  • tsconfig: Per-package configs extending a shared base with moduleResolution: "Bundler"

Reproduction

Project structure (simplified):

repo-root/
├── node_modules/          # all dependencies hoisted here
├── package.json           # workspaces: ["apps/*", "packages/*"]
├── packages/
│   └── ui/
│       ├── tsconfig.json  # extends shared base config
│       ├── types.ts
│       ├── node_modules/  # only contains .bin (no packages)
│       └── components/atoms/button.tsx
└── apps/
    └── my-app/
        ├── tsconfig.json
        ├── node_modules/  # only contains .bin
        └── src/App.tsx

Steps:

  1. Enable the typescript-lsp plugin
  2. Open any .tsx file in a monorepo package (e.g., packages/ui/components/atoms/button.tsx)
  3. Use LSP tool with findReferences on an exported function
  4. Observe: "No references found"
  5. Use LSP tool with hover — returns no content but triggers TS diagnostics showing module resolution failures:
  • Cannot find module '../../types' or its corresponding type declarations. [2307]
  • This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. [2875]
  1. Use LSP tool with workspaceSymbolworks correctly, finds symbols

Root Cause Analysis

Yarn 1 hoists all dependencies to the repo-root node_modules/. Individual packages have only .bin in their local node_modules/.

The tsserver instance spawned by the plugin appears to set its project root to the individual package directory rather than the monorepo root. This means it cannot resolve:

  • Dependencies like react (hoisted to root)
  • Shared config packages (resolved via root node_modules)
  • Cross-package type imports

Since workspaceSymbol uses text-based scanning (doesn't require type resolution), it works. All semantic operations (findReferences, hover, goToDefinition, documentSymbol) require a resolved module graph and therefore fail.

Expected Behavior

The LSP plugin should detect the monorepo root (e.g., by walking up to find the root package.json with workspaces) and configure tsserver with the correct project root so that hoisted node_modules are resolved.

Related Issues

  • #15235 — plugin.json missing (different issue)
  • #14803 — LSP plugins not recognized (different issue)
  • #16291 — TypeScript LSP Plugin Not Registering (different issue)

Workaround

Currently none for semantic operations. workspaceSymbol can be used as a partial workaround for symbol discovery only.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗