Skip to content

[BUG] enablement: false` (boolean) on a command breaks command registration for all extensions loaded afterwards #194

Description

@d-biehl

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

  1. Install the Hatch extension (pypa.hatch 0.2.0) alongside a handful of other extensions that contribute commands (e.g. rust-analyzer, CodeLLDB, RobotCode).
  2. Reload / start VS Code.
  3. 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.
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions