Skip to content

Binary resolution in multi-root workspaces can pick the wrong version #145

@leaysgur

Description

@leaysgur

In a multi-root workspace, the extension resolves a single oxlint|oxfmt binary for all workspace folders. The resolution order is:

  • 1: require.resolve("oxlint") across all workspace folder paths
  • 2: node_modules/.bin/oxlint lookup across all workspace folders

export async function searchProjectNodeModulesBin(binaryName: string): Promise<string | undefined> {

Since only one LSP process serves all workspaces, the first resolved binary is used for all.

If different workspaces have different versions installed, the older one may silently be used for workspaces that depend on a newer version.

There's no way to control which binary is used per workspace folder?

Workspace (multi-root)
├── workspace-a/
│   ├── node_modules/
│   │   └── oxfmt@0.36.0        ← require.resolve("oxfmt") hits here first
│   └── package.json
└── workspace-b/
    ├── node_modules/
    │   └── oxfmt@0.39.0        ← never used!
    └── package.json

This also applies to oxlint.

If this is the intended design, then the answer to "How can I use the desired version?" would be, "Close conflicting workspaces or rearrange their order."

Does that make sense...?


Context: Vite+

When vite-plus re-exports oxlint|oxfmt via node_modules/.bin/oxfmt (without installing oxfmt as a direct dependency), require.resolve("oxfmt") won't find it at all.

It only gets picked up in the .bin/ fallback step. So a direct oxfmt dependency in another workspace always wins, regardless of version.

This is especially problematic because recent versions of oxlint|oxfmt added support for reading the .lint|fmt field from vite.config.ts.
If an older binary is resolved from another workspace, this config is silently ignored and falls back to defaults.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions