First off — thanks a lot for building and maintaining the Hatch extension! Having first-class Hatch support in VS Code is genuinely helpful and much appreciated.
While using it I came across an issue I wanted to report:
Summary
The hatch.envInterpreter command is contributed with "enablement": false — a boolean, but the enablement field must be a string (a when-clause expression). While registering command contributions, VS Code throws a TypeError on this value and aborts the commands extension-point handler part-way through its list of contributors (mechanism in Root cause).
The effect is order-dependent: the handler registers extensions' command contributions in sequence, and the TypeError aborts it at Hatch's entry. Every extension whose commands are processed after Hatch never gets its commands registered — they are missing from the Command Palette entirely, and anything bound to them (keybindings, menu items, views) stops working. The log shows the triggering TypeError: this._input.charCodeAt is not a function, and VS Code additionally logs Menu item references a command \…` which is not defined in the 'commands' section.` for each of those extensions' menu items, even though those commands are perfectly well-defined (rust-analyzer, CodeLLDB, Slint, Even Better TOML, RobotCode, …). Extensions processed before Hatch are unaffected.
This is pure manifest parsing, so it is platform-independent — reproduced on Linux and Windows, on both VS Code stable and VS Code Insiders. A single malformed field in one extension silently breaks unrelated extensions, which makes it more than a cosmetic schema slip.
Offending contribution
package.json (Hatch extension):
{
"command": "hatch.envInterpreter",
"title": "Hatch: Get an environment’s interpreter path",
"enablement": false
}
Per the VS Code contribution-point schema, command.enablement is a when-clause and must be a string.
Steps to reproduce
- Install the Hatch extension (
pypa.hatch 0.2.0) alongside a handful of other extensions that contribute commands (e.g. rust-analyzer, CodeLLDB, RobotCode).
- Reload / start VS Code.
- Open the Command Palette (Ctrl+Shift+P) and search for a command that is normally provided by one of the other installed extensions (e.g.
rust-analyzer: Run, LLDB: …, RobotCode: …). The command is missing — none of that extension's commands are listed anymore.
- Confirm in the log: Command Palette → Developer: Open Logs Folder → newest
window*/renderer.log (or Developer: Toggle Developer Tools → Console). You will see a TypeError: this._input.charCodeAt is not a function followed by a Menu item references a command \…` which is not defined in the 'commands' section.` line for each affected menu item (see the log excerpt below).
Log output
The triggering TypeError, followed by one "command not defined" line per affected menu item (the commands themselves are defined — they were just never registered):
[error] this._input.charCodeAt is not a function: TypeError: this._input.charCodeAt is not a function
at a._advance (… workbench.desktop.main.js)
at a.scan (…)
at a.parse (…)
at x.deserialize (…)
at … _handler (…)
at … _handleExtensionPoint (…)
at … _doHandleExtensionPoints (…)
at … _resolveAndProcessExtensions (…)
at async … _initialize (…)
[error] [rust-lang.rust-analyzer]: Menu item references a command `rust-analyzer.run` which is not defined in the 'commands' section.
[error] [vadimcn.vscode-lldb]: Menu item references a command `lldb.modules.copyValue` which is not defined in the 'commands' section.
[error] [d-biehl.robotcode]: Menu item references a command `robotcode.runCurrentFile` which is not defined in the 'commands' section.
...
Root cause
enablement: false is a boolean. VS Code parses enablement as a context-key expression via ContextKeyExpr.deserialize, whose Scanner does this._input.charCodeAt(...). A boolean has no charCodeAt, so it throws and unwinds out of the commands extension-point handler mid-iteration — every contributor queued after Hatch is skipped, so those extensions' commands are never registered.
Suggested fix
If the intent is to hide the command (it looks like an internal/programmatic command not meant for the Command Palette), use a string when-clause:
{
"command": "hatch.envInterpreter",
"title": "Hatch: Get an environment’s interpreter path",
"enablement": "false"
}
Alternatively, drop enablement entirely and hide it from the palette via a menu entry:
"menus": {
"commandPalette": [
{ "command": "hatch.envInterpreter", "when": "false" }
]
}
Either way the value passed to the context-key parser must be a string.
Environment
- Hatch extension:
pypa.hatch 0.2.0
- VS Code: 1.122.1 (stable) and VS Code Insiders
- OS: reproduced on Linux (x64) and Windows; not tested on macOS, but the cause is OS-agnostic (manifest parsing)
- Also present (Hatch dependency, not the cause):
ms-python.vscode-python-envs 1.30.0
Thanks and best regards
First off — thanks a lot for building and maintaining the Hatch extension! Having first-class Hatch support in VS Code is genuinely helpful and much appreciated.
While using it I came across an issue I wanted to report:
Summary
The
hatch.envInterpretercommand is contributed with"enablement": false— a boolean, but theenablementfield must be a string (awhen-clause expression). While registering command contributions, VS Code throws aTypeErroron this value and aborts thecommandsextension-point handler part-way through its list of contributors (mechanism in Root cause).The effect is order-dependent: the handler registers extensions' command contributions in sequence, and the
TypeErroraborts it at Hatch's entry. Every extension whose commands are processed after Hatch never gets its commands registered — they are missing from the Command Palette entirely, and anything bound to them (keybindings, menu items, views) stops working. The log shows the triggeringTypeError: this._input.charCodeAt is not a function, and VS Code additionally logsMenu item references a command \…` which is not defined in the 'commands' section.` for each of those extensions' menu items, even though those commands are perfectly well-defined (rust-analyzer, CodeLLDB, Slint, Even Better TOML, RobotCode, …). Extensions processed before Hatch are unaffected.This is pure manifest parsing, so it is platform-independent — reproduced on Linux and Windows, on both VS Code stable and VS Code Insiders. A single malformed field in one extension silently breaks unrelated extensions, which makes it more than a cosmetic schema slip.
Offending contribution
package.json(Hatch extension):{ "command": "hatch.envInterpreter", "title": "Hatch: Get an environment’s interpreter path", "enablement": false }Per the VS Code contribution-point schema,
command.enablementis awhen-clause and must be a string.Steps to reproduce
pypa.hatch0.2.0) alongside a handful of other extensions that contribute commands (e.g. rust-analyzer, CodeLLDB, RobotCode).rust-analyzer: Run,LLDB: …,RobotCode: …). The command is missing — none of that extension's commands are listed anymore.window*/renderer.log(or Developer: Toggle Developer Tools → Console). You will see aTypeError: this._input.charCodeAt is not a functionfollowed by aMenu item references a command \…` which is not defined in the 'commands' section.` line for each affected menu item (see the log excerpt below).Log output
The triggering
TypeError, followed by one "command not defined" line per affected menu item (the commands themselves are defined — they were just never registered):Root cause
enablement: falseis a boolean. VS Code parsesenablementas a context-key expression viaContextKeyExpr.deserialize, whoseScannerdoesthis._input.charCodeAt(...). A boolean has nocharCodeAt, so it throws and unwinds out of thecommandsextension-point handler mid-iteration — every contributor queued after Hatch is skipped, so those extensions' commands are never registered.Suggested fix
If the intent is to hide the command (it looks like an internal/programmatic command not meant for the Command Palette), use a string
when-clause:{ "command": "hatch.envInterpreter", "title": "Hatch: Get an environment’s interpreter path", "enablement": "false" }Alternatively, drop
enablemententirely and hide it from the palette via a menu entry:Either way the value passed to the context-key parser must be a string.
Environment
pypa.hatch0.2.0ms-python.vscode-python-envs1.30.0Thanks and best regards