{"record":{"id":"49fc73ba189a24d2","repo":"withastro/astro","slug":"bad-request-49fc73","errorCode":"BAD_REQUEST","errorMessage":"Failed to validate: ${JSON.stringify(issues, null, 2)}","messagePattern":"Failed to validate: (.+?)","errorType":"validation","errorClass":"ActionInputError","httpStatus":400,"severity":"error","filePath":"packages/astro/src/actions/runtime/server.ts","lineNumber":91,"sourceCode":"\nfunction getFormServerHandler<TOutput, TInputSchema extends z.$ZodType>(\n\thandler: ActionHandler<TInputSchema, TOutput>,\n\tinputSchema?: TInputSchema,\n) {\n\treturn async (unparsedInput: unknown, context: ActionAPIContext): Promise<Awaited<TOutput>> => {\n\t\tif (!(unparsedInput instanceof FormData)) {\n\t\t\tthrow new ActionError({\n\t\t\t\tcode: 'UNSUPPORTED_MEDIA_TYPE',\n\t\t\t\tmessage: 'This action only accepts FormData.',\n\t\t\t});\n\t\t}\n\n\t\tif (!inputSchema) return await handler(unparsedInput, context);\n\n\t\tconst parsed = await parseFormInput(inputSchema, unparsedInput);\n\n\t\tif (!parsed.success) {\n\t\t\tthrow new ActionInputError(parsed.error.issues);\n\t\t}\n\t\treturn await handler(parsed.data, context);\n\t};\n}\n\nasync function parseFormInput(inputSchema: z.$ZodType, unparsedInput: FormData) {\n\tconst baseSchema = unwrapBaseZ4ObjectSchema(inputSchema, unparsedInput);\n\tconst input =\n\t\tbaseSchema instanceof z.$ZodObject\n\t\t\t? formDataToObject(unparsedInput, baseSchema)\n\t\t\t: unparsedInput;\n\n\tconst parsed = await z.safeParseAsync(inputSchema, input);\n\treturn parsed;\n}\n\nfunction getJsonServerHandler<TOutput, TInputSchema extends z.$ZodType>(\n\thandler: ActionHandler<TInputSchema, TOutput>,","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/actions/runtime/server.ts#L73-L109","documentation":"After converting FormData against the action's zod input schema (parseFormInput), validation failed. The handler throws ActionInputError carrying the zod issues, surfaced to the caller as ActionError code BAD_REQUEST (400).","triggerScenarios":"A form submission whose fields do not satisfy the schema: missing required fields, wrong types, failed refinements, or field names that do not match schema keys.","commonSituations":"User submits an incomplete form; HTML input names differ from zod keys; type mismatch (string where number expected); file field not allowed by schema.","solutions":["Inspect the error with isInputError(error) and read error.fields to display per-field messages.","Align the form input names with the zod schema keys (including nested prefixes).","Add matching client-side validation so invalid forms are caught before submission."],"exampleFix":"// before - schema wants a number age, form sends string and is missing it\nconst input = z.object({ name: z.string(), age: z.number() });\n// after - use coercion + optional handling, and check error.fields on the client\nconst input = z.object({\n  name: z.string().min(1),\n  age: z.coerce.number().int().nonnegative(),\n});\n// client\nconst { data, error } = await actions.signup.orThrow(fd);\nif (isInputError(error)) showError(error.fields);","handlingStrategy":"try-catch","validationCode":"// Validate form input against the same zod schema on the client before calling.\nconst parsed = subscribeSchema.safeParse(Object.fromEntries(new FormData(formEl)));\nif (!parsed.success) showFieldErrors(parsed.error.issues);","typeGuard":"// On the result, narrow to an input error to read field issues.\nfunction isInputError(e: unknown): e is { fields: Record<string, string[]> } {\n  return e instanceof ActionError && (e as any).fields !== undefined;\n}","tryCatchPattern":"const { data, error } = await actions.signup(fd);\nif (isInputError(error)) {\n  for (const [field, msgs] of Object.entries(error.fields)) showFieldError(field, msgs.join(', '));\n}","preventionTips":["Reuse the action's zod schema on the client for pre-validation.","Keep HTML input names aligned with schema keys.","Always handle isInputError to render field-level messages."],"tags":["actions","validation","zod","form-data"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}