Question
Getting error: Failed to parse body as FormData in Next.js 14 app router
I have a Next 14 app router project, so the problem is in the dashboard page and in a more clear way in the add and update form, I'm using Formik to handle the forms and then I send the data as FormData to a server action which sends the data again to a route handler in FormData formate like:
Client
const handleSubmit = async (values: t_formValues, submitProps: FormikHelpers<t_formValues>): Promise<void> => {
const formData: FormData = new FormData();
if (values && values.cover) {
// Stringify title, overview, description
const _values = {...values, title: JSON.stringify(values.title), overview: JSON.stringify(values.overview), description: JSON.stringify(values.description)};
formData.append("files.cover", values.cover as File);
formData.append("data", JSON.stringify(Object.fromEntries(Object.entries(_values).filter(([key, value]) => key !== "cover"))));
}
const json = await Services.updateOne(serviceID, formData);
}
Server Action
const updateOne = async (serviceID: number, serviceDetails: FormData): Promise<{ data: t_service } | { data: null, errorCode: t_errorCode }> => {
const res = await fetch(`${process.env.NEXT_PUBLIC_DOMAIN}/api/services`, {
method: "PUT",
headers: {
"serviceID": serviceID.toString()
},
body: serviceDetails,
})
const json: { data: t_service, error?: Error } = await res.json();
if (!res.ok) {
throw json.error;
}
return { data: json.data };
}
Route handler
export async function PUT(request: Request) {
const headersList = headers();
const serviceID = headersList.get("serviceID");
const formData: FormData = await request.formData();
const res = await fetch(`${process.env.API_ENDPOINT}/services/${serviceID}`, {
method: "PUT",
headers: {
"Authorization": `Bearer ${process.env.NEXT_SERVER_REST_API_KEY}`,
},
body: formData,
});
const json = await res.json();
if (!res.ok) {
throw json.error;
}
return Response.json({
...json
}, { status: res.status })
}
After submitting I'm getting the following error in Vercel logs
TypeError: Failed to parse body as FormData.
at node:internal/deps/undici/undici:4249:27
at successSteps (node:internal/deps/undici/undici:4288:27)
at fullyReadBody (node:internal/deps/undici/undici:2724:9)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async consumeBody (node:internal/deps/undici/undici:4297:7)
at async m (/var/task/.next/server/app/api/services/route.js:1:3102)
at async /var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:42484
at async eI.execute (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:32486)
at async eI.handle (/var/task/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js:6:43737)
at async Y (/var/task/node_modules/next/dist/compiled/next-server/server.runtime.prod.js:16:24556)
I expected it to work correctly like the development environment but the error above thrown in the production env
Edit
I have noticed that the "data" field is sent correctly from the client side but arrived at the server action without the last 25% of its content, I don't know if this stuff caused the error