Skip to content

[rush-serve-plugin] The auto-picked port never reaches the port parameter: _value is ignored since ts-command-line uses #value #6144

Open

Description

Summary

When rush start (or another watch-mode phased command with portParameterLongName) runs without an explicit port, @rushstack/rush-serve-plugin listens on an OS-assigned port and then tries to publish it through the command-line parameter, so that other plugins (and the operations that receive the parameter) see the real port. It does so by writing portParameter._value. Since @rushstack/ts-command-line switched parameters to native private fields (#5943), CommandLineIntegerParameter stores its value in #value, so the assignment only adds an unused property. portParameter.value stays undefined, and nothing downstream sees the port.

Versions

Repro

  1. Configure rush-serve-plugin with portParameterLongName: "--port", and define --port as an integer parameter of the start command, associated with a phase.
  2. Add a second plugin that taps createOperationsAsync after the serve plugin (any stage above -1) and logs context.customParameters.get('--port').value.
  3. Run rush start without --port.

Expected

The serve plugin logs Content is being served from: https://localhost:<port>/, and the second plugin logs the same <port>.

Actual

The second plugin logs undefined. An explicit --port 4321 works, because then the value comes from the parser.

Code pointer (main)

  • rush-plugins/rush-serve-plugin/src/phasedCommandHandler.ts, line 241: (portParameter as unknown as { _value?: string })._value = `${activePort}`;
  • libraries/ts-command-line/src/parameters/CommandLineIntegerParameter.ts: the value lives in #value and is written only by _setValue().

Suggested fix

Set the value through the parameter's setter (it also stores a number, as the integer parameter expects, instead of a string):

(portParameter as unknown as { _setValue(data: unknown): void })._setValue(activePort);

Since _setValue is @internal, a public way for a plugin to override a parsed parameter value (or a session-level API that publishes the serve plugin's active port) would avoid the cast. A unit test that runs the handler with port 0 and checks portParameter.value would catch a regression.

Filed with help from GitHub Copilot (AI); reviewed by the reporter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Needs triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions