fix(site): resolve WS/HTTP race condition on workspace parameters page (backport v2.29) (#24249)

Cherry-pick of
https://github.com/coder/coder/commit/17d214b4a4a75a39fc499784dd2e65f81b7cdcf1
onto `release/2.29`.

Original PR: #22556

When the workspace parameters page loads, the WebSocket sends an initial
response with template defaults. For parameters with no default, the
server returns `{valid: false, value: ""}`. On first render,
`useSyncFormParameters` overwrites the form's correctly-autofilled value
with `""`. This fix preserves the current form value when the server
value is `{valid: false}`.

Fixes the consistently failing e2e test `create workspace with default
and required parameters`.

> 🤖 Generated by Coder Agents

Co-authored-by: Kyle Carberry <kyle@coder.com>
This commit is contained in:
Garrett Delfosse
2026-04-10 13:44:48 -04:00
committed by GitHub
parent f8edef292f
commit ccba5732aa
@@ -27,16 +27,30 @@ export function useSyncFormParameters({
useEffect(() => {
if (!parameters) return;
const currentFormValues = formValuesRef.current;
const newParameterValues = parameters.map((param) => ({
name: param.name,
value: param.value.valid ? param.value.value : "",
}));
const currentFormValuesMap = new Map(
currentFormValues.map((value) => [value.name, value.value]),
);
const newParameterValues = parameters.map((param) => {
// When the server value is not valid (e.g., the initial
// WebSocket response before any user input is sent),
// preserve the current form value. This prevents the sync
// hook from overwriting autofilled values (from the
// previous build) with empty strings before the server
// has had a chance to process them.
if (!param.value.valid) {
const existingValue = currentFormValuesMap.get(param.name);
if (existingValue !== undefined) {
return { name: param.name, value: existingValue };
}
}
return {
name: param.name,
value: param.value.valid ? param.value.value : "",
};
});
const isChanged =
currentFormValues.length !== newParameterValues.length ||
newParameterValues.some(