Astro Info
Astro v5.x (latest)
Node v22.x
Package manager pnpm
Platform linux
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
z.array(z.boolean()) in a form action always converts every non-empty string value to true, making it impossible to pass false through a form data array.
The bug is in handleFormDataGetAll() at line 411 of packages/astro/src/actions/runtime/server.ts:
function handleFormDataGetAll(key: string, formData: FormData, validator: z.$ZodArray) {
const entries = Array.from(formData.getAll(key));
const elementValidator = validator._zod.def.element;
if (elementValidator instanceof z.$ZodNumber) {
return entries.map(Number);
} else if (elementValidator instanceof z.$ZodBoolean) {
return entries.map(Boolean); // BUG: Boolean("false") === true
}
return entries;
}
FormData values are always strings. Boolean("false") === true and Boolean("0") === true because JavaScript's Boolean() coercion treats any non-empty string as truthy. The string "false" is not an empty string, so it becomes true.
The single-boolean path in formDataToObject() at line 389 already implements the correct logic:
} else if (validator instanceof z.$ZodBoolean) {
const val = formData.get(prefixedKey);
obj[key] = val === 'true' ? true : val === 'false' ? false : formData.has(prefixedKey);
}
The array path is inconsistent — it should apply the same string comparison per entry instead of map(Boolean):
return entries.map(v => v === 'true' ? true : v === 'false' ? false : Boolean(v));
The existing test suite in packages/astro/test/units/actions/form-data-to-object.test.ts covers single z.boolean() with "false" values (line 51–66) and number/string arrays, but has no test for z.array(z.boolean()).
What's the expected result?
A form submission with three boolean array values ["false", "true", "false"] should produce [false, true, false]. Currently it produces [true, true, true].
Link to Minimal Reproducible Example
https://github.com/Hunnyboy1217/astro-action-boolean-array-repr
Participation
Astro Info
If this issue only occurs in one browser, which browser is a problem?
No response
Describe the Bug
z.array(z.boolean())in a form action always converts every non-empty string value totrue, making it impossible to passfalsethrough a form data array.The bug is in
handleFormDataGetAll()at line 411 ofpackages/astro/src/actions/runtime/server.ts:FormDatavalues are always strings.Boolean("false") === trueandBoolean("0") === truebecause JavaScript'sBoolean()coercion treats any non-empty string as truthy. The string"false"is not an empty string, so it becomestrue.The single-boolean path in
formDataToObject()at line 389 already implements the correct logic:The array path is inconsistent — it should apply the same string comparison per entry instead of
map(Boolean):The existing test suite in
packages/astro/test/units/actions/form-data-to-object.test.tscovers singlez.boolean()with"false"values (line 51–66) and number/string arrays, but has no test forz.array(z.boolean()).What's the expected result?
A form submission with three boolean array values
["false", "true", "false"]should produce[false, true, false]. Currently it produces[true, true, true].Link to Minimal Reproducible Example
https://github.com/Hunnyboy1217/astro-action-boolean-array-repr
Participation