On activation, Pyrefly silently writes
disableLanguageServices = true
to the user's
global
VS Code settings for three named third-party extensions, without prompting
the user or notifying them in any way. These settings are
never restored
when
Pyrefly is deactivated or uninstalled, leaving those extensions permanently broken
until the user manually intervenes.
This has been verified by live reproduction on a real machine (see below).
Affected extensions
detachhead.basedpyright
codeium.windsurfpyright
anysphere.cursorpyright
Source
lsp/src/extension-interop.ts
:
export
async
function
disableWindsurfPyrightIfInstalled
(
)
{
const
windsurfPyrightExtension
=
vscode
.
extensions
.
getExtension
(
'codeium.windsurfpyright'
)
;
if
(
windsurfPyrightExtension
)
{
const
config
=
vscode
.
workspace
.
getConfiguration
(
'windsurfPyright'
)
;
await
config
.
update
(
'disableLanguageServices'
,
true
,
vscode
.
ConfigurationTarget
.
Global
)
;
}
}
export
async
function
disableBasedPyrightIfInstalled
(
)
{
const
basedPyrightExtension
=
vscode
.
extensions
.
getExtension
(
'detachhead.basedpyright'
)
;
if
(
basedPyrightExtension
)
{
const
config
=
vscode
.
workspace
.
getConfiguration
(
'basedpyright'
)
;
await
config
.
update
(
'disableLanguageServices'
,
true
,
vscode
.
ConfigurationTarget
.
Global
)
;
}
}
export
async
function
disableCursorPyrightIfInstalled
(
)
{
const
cursorPyrightExtension
=
vscode
.
extensions
.
getExtension
(
'anysphere.cursorpyright'
)
;
if
(
cursorPyrightExtension
)
{
const
config
=
vscode
.
workspace
.
getConfiguration
(
'cursorpyright'
)
;
await
config
.
update
(
'disableLanguageServices'
,
true
,
vscode
.
ConfigurationTarget
.
Global
)
;
}
}
These are called unconditionally in
lsp/src/extension.ts
on activation.
Relevant commits:
69985d1d
,
c0ab0d76
,
72458900
,
2fb5205a
(December 8-9, 2025)
Why this is a problem
1. Silent global modification
ConfigurationTarget.Global
writes to the user's global
settings.json
, affecting
every workspace on the machine. The user receives no notification, no prompt, no
indication this has occurred.
2. No cleanup on deactivation or uninstall
There is no corresponding
deactivate()
logic that restores these settings.
A user who installs Pyrefly, then uninstalls it, is left with basedpyright,
windsurfpyright, or cursorpyright silently broken — with no obvious cause.
They would need to know to manually find and delete these keys from their
global
settings.json
to restore functionality.
3. Targets extensions by publisher ID
This is not a generic "disable conflicting language servers" mechanism.
It hardcodes the extension IDs of specific named competitors and disables
them individually. The user has no opt-out.
Live reproduction
Reproduced independently on both VSCodium and stock VS Code 1.118.1.
Test 1 — VSCodium
Tested with
detachhead.basedpyright
installed.
~/.config/VSCodium/User/settings.json
before installing Pyrefly:
{
"python.languageServer"
:
"
Default
"
}
After installing Pyrefly and opening a single Python file:
{
"python.languageServer"
:
"
Default
"
,
"basedpyright.disableLanguageServices"
:
true
}
After uninstalling Pyrefly:
{
"python.languageServer"
:
"
Default
"
,
"basedpyright.disableLanguageServices"
:
true
}
The key persists. basedpyright remains broken with no indication of why.
Test 2 — VS Code 1.118.1 (clean isolated profile)
To rule out any VSCodium-specific behaviour, reproduced on stock VS Code using a
completely clean profile (
--user-data-dir /tmp/vscode-test-profile
) with no prior
configuration.
settings.json
before installing Pyrefly:
file did not exist (empty profile)
After installing
detachhead.basedpyright
, then
meta.pyrefly
, and opening a single Python file:
{
"python.languageServer"
:
"
None
"
,
"basedpyright.disableLanguageServices"
:
true
}
Same result. The write happens on first Python file open regardless of editor or prior configuration.
Expected behavior
If Pyrefly needs exclusive access to Python language services to function correctly,
it should:
Ask the user
before modifying settings owned by other extensions
Restore those settings
in
deactivate()
when Pyrefly is disabled or uninstalled
Or at minimum,
log what it changed
so users can reverse it
Additional concern: forced Microsoft extension dependencies
package.json
declares
"extensionDependencies": ["ms-python.python"]
.
VSCodium and VS Code treat this as a hard bidirectional lock — installing Pyrefly
automatically installs:
ms-python.python
ms-python.debugpy
ms-python.vscode-python-envs
Uninstalling any of those three also uninstalls Pyrefly.
The only thing
ms-python.python
is used for is querying the active Python interpreter
path for the optional "Run File / Run Test" CodeLens buttons. The core LSP features
(type checking, completions, hover, go-to-definition) run entirely through the
pyrefly
binary and have no dependency on
ms-python.python
at all.
For users on VSCodium or other FOSS VS Code distributions who specifically avoid
Microsoft extensions, this is a significant and undisclosed side effect of installing
what is presented as an independent open source tool.
Steps to reproduce
Install
detachhead.basedpyright
and confirm it is working (completions, hover, etc.)
Install
meta.pyrefly
Open a Python file (triggers Pyrefly activation)
Check your global
settings.json

basedpyright.disableLanguageServices
is now
true
Uninstall
meta.pyrefly
Observe that
basedpyright.disableLanguageServices
remains
true
— basedpyright
is still broken with no indication of why