Skip to content

linter: --lsp mode does not apply plugins re-added via extends (CLI works, --print-config correct, LSP returns empty #22758

@kerwanp

Description

@kerwanp

What version of Oxlint are you using?

1.67.0 (also reproduced with 1.66.0)

What command did you run?

oxlint --lsp (launched by neovim's nvim-lspconfig oxlint server, but reproduces with any LSP client). CLI comparison: oxlint app/path/to/file.ts from the child config directory.

What does your .oxlintrc.json (or oxlint.config.ts) config file look like?

Workspace root : .oxlintrc.json:

{
  "$schema": "./node_modules/oxlint/configuration_schema.json",
  "plugins": ["import", "promise", "node"],
  "categories": {
    "correctness": "error",
    "suspicious": "warn",
    "perf": "warn"
  },
  "rules": {
    "typescript/consistent-type-imports": ["warn", { "prefer": "type-imports" }]
  }
}

Child : apps/api/.oxlintrc.json:

{
  "$schema": "../../node_modules/oxlint/configuration_schema.json",
  "extends": ["../../.oxlintrc.json"],
  "ignorePatterns": ["database/schema.ts", ".adonisjs"],
  "rules": {
    "unicorn/filename-case": ["error", { "case": "snakeCase" }]
  }
}

What happened?

When the root config declares an explicit plugins array, the default-on plugins (typescript, unicorn, oxc) are dropped from that config : --print-config from the root confirms this. The child config has no plugins field, so via extends the defaults are merged back in, and --print-config from apps/api/ correctly shows all six plugins.

CLI behaves consistently with --print-config:

# From apps/api/  (extends merges defaults back in)
$ oxlint app/auth/guard/firebase.ts
app/auth/guard/firebase.ts:5:1: warning typescript(consistent-type-imports): ...
app/auth/guard/firebase.ts:6:1: warning typescript(consistent-type-imports): ...
app/auth/guard/firebase.ts:8:1: warning typescript(consistent-type-imports): ...
app/auth/guard/firebase.ts:11:30: error typescript(no-wrapper-object-types): ...

LSP does not:

Launching oxlint --lsp with cwd = apps/api and sending textDocument/diagnostic for the exact same file returns:

{ "items": [], "kind": "full" }

Verified via /proc//cwd that the LSP process really is running in apps/api, and via --print-config from that same cwd that the resolved config includes the typescript/unicorn/oxc plugins. So the LSP is reading the right config on disk, but is not applying the plugins that were re-added through extends. it behaves as if it were using the parent config's literal plugins array.

Expected Behavior

oxlint --lsp should produce the same diagnostics as the CLI when given the same cwd, the same binary, and the same config tree, in particular, plugins re-added via extends (by virtue of the child config omitting plugins) should be active.

Actual Behavior

LSP returns zero diagnostics; CLI returns four. --print-config agrees with the CLI.

Workaround

Add the default plugins explicitly to the root config so neither path relies on the extends merge:

"plugins": ["import", "promise", "node", "typescript", "unicorn", "oxc"]

Related

Possibly the same root cause as the (closed) #21030, which also reports --print-config disagreeing with lint-time behavior under nested/extended configs. That issue was closed without a stated fix and the underlying mismatch still reproduces on 1.67.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions