Quick Answer
Vite fixes a configuration-merge crash involving server.ws set to false and a merged hot-module-replacement configuration. A missing property descriptor is now checked before it is reused.
In Plain English
Projects often combine a shared configuration with local settings. Hot module replacement, or HMR, updates a page during development without a full reload. WebSocket settings help control that connection. A configuration can deliberately disable the WebSocket server while still carrying HMR options from another layer.

Code Evidence
The change is in mergeConfigRecursively in packages/vite/src/node/utils.ts. Instead of assuming Object.getOwnPropertyDescriptor always returns a descriptor, the code saves the result and calls Object.defineProperty only when it exists. A new test combines ws: false with HMR host and port settings, then checks that the disabled value survives and HMR remains an object.
Why a property descriptor can be absent
A property descriptor describes how a property behaves, including whether its value can be changed or whether access goes through a getter. It is not the same thing as the property's current value. Looking up a descriptor is allowed to return nothing when the property is absent. Passing that missing result onward as though it were a valid descriptor turns a normal shape difference into an exception. The new guard places the existence check at precisely that handoff.
That detail matters when configurations combine different representations. One branch can hold an explicit boolean false while a related branch contains an object of HMR settings. A merge helper cannot safely infer that both branches expose matching properties merely because their options are related. The patch keeps the descriptor lookup, stores its result, and makes the property-definition step conditional. It avoids inventing a replacement descriptor when the source does not provide one.
A shared preset meets a local override
Imagine a shared development preset that supplies an HMR host and port for a team's environment. A consuming application deliberately sets server.ws to false because its development setup manages the connection differently. Both choices can arrive at the same merge operation even though they originated in different files. The relevant question at this stage is whether that operation completes while preserving the explicit disabled value and retaining HMR's object shape. That is the behavior covered by the new regression case.
This scenario is an illustration of the configuration shape, not a claim that the patch configures an external connection automatically. Merging settings and establishing a working browser connection are distinct stages. A server that now gets past configuration processing can still have an incorrect host, an unreachable port, or an application-specific expectation about how updates travel. The source change gives developers a narrower starting point: first establish that the merge succeeds, then inspect the live connection if a symptom remains.
A useful verification sequence
Reproduce the merge with the actual preset and local override used by the project. Record the resulting server.ws value and the HMR value's type, and check that no descriptor-related exception is raised. Include the explicit false case in any regression coverage for an internal preset helper. Testing only absent settings or ordinary option objects would miss the meaningful boolean branch. Preserve the order of the inputs as well, since a merge test should represent the same precedence rules as the application.
After that focused check, start the real development environment and exercise the update behavior it is intended to support. If a separate service owns the connection, inspect that arrangement directly instead of assuming the merge assertion proves connectivity. The upstream test provides evidence for the configuration operation; a browser session supplies different evidence about the application. This separation makes a failed check actionable without overstating what a passing unit test guarantees.
For maintainers of merge utilities, the general lesson is to preserve intentional values and verify assumptions at conversion boundaries. A boolean is a valid configuration choice even when a neighboring setting is an object. The small existence guard is valuable because it follows that rule without broadening the public setting or replacing the overall merge algorithm.
Why It Matters
The practical lesson for a shared toolchain is that false is an intentional setting, not missing data. Teams building configuration presets can use this case to examine their own merge helpers. A defensive existence check is especially useful when related options have different shapes: one can be a boolean while another is a structured object.
An Open Question
Does the resulting HMR configuration behave as a particular application expects when WebSockets are disabled? The added regression test checks merging and the resulting value shapes. It does not demonstrate every possible live-reload arrangement.
Scope and Limitations
This is source and test inspection, not a browser-level reproduction. The fix appears in Vite 8.3.1, and its scope is the merge operation.
