Troubleshooting Formidable's form.parse in a Nuxt3 API Integration

Hello everyone,

We’re currently integrating the ClickUp API into a project built with Nuxt3 and have encountered some challenges.

Initially, we faced an issue where API POST requests worked fine locally and on Heroku, but failed on Netlify. We resolved this by replacing our existing function for reading the request body:

export async function readRequestBody(req: IncomingMessage): Promise<any> {
    return new Promise((resolve, reject) => {
        let data = '';
        req.on('data', (chunk: Buffer | string) => {
            data += chunk.toString();
        });
        req.on('end', () => {
            try {
                const parsedData = JSON.parse(data);
                resolve(parsedData);
            } catch (err) {
                reject(err);
            }
        });
        req.on('error', (err: Error) => {
            reject(err);
        });
    });
}

with a simpler approach:
const requestBody = await readBody(event);

This change effectively addressed the problem. However, we are now stuck with a file uploading function that, similar to the previous issue, works locally and on Heroku but not on Netlify.

On Netlify, the process results in a 502 error, and we’re unable to proceed beyond the parsing stage with Formidable’s form.parse method.
We are especially puzzled because we cannot create logs within the form.parse method of Formidable; it simply doesn’t work or return anything when deployed on Netlify:

import axios from 'axios';
import { defineEventHandler } from 'h3';
import FormData from 'form-data';
import { Formidable } from 'formidable';
import fs from 'fs'; 

export default defineEventHandler(async (event) => {
    console.log("Received request for file upload");

    const form = new Formidable();
    
    // Using Formidable's parse method in a promise, we create the object containing both fields and files
    const parsedData = await new Promise((resolve, reject) => {
        form.parse(event.node.req, (err, fields, files) => {
            if (err) {
                reject(err);
            } else {
                resolve({ fields, files });
            }
        });
    });

    // Extract taskId from the fields
    const taskId = parsedData.fields.taskId;

    if (!taskId) {
        throw new Error('Task ID not provided');
    }

    // Check if a file is provided
    if (!parsedData.files || !parsedData.files.attachment) {
        throw new Error('No file provided');
    }

    const file = parsedData.files.attachment;
    const fileToAppend = Array.isArray(file) ? file[0] : file;
    const fileStream = fs.createReadStream(fileToAppend.filepath);

    // Prepare FormData for the axios request
    const formData = new FormData();
    formData.append("attachment", fileStream, fileToAppend.originalFilename);

    // axios POST request with form data
    const resp = await axios.post(
        `https://api.clickup.com/api/v2/task/${taskId}/attachment`, 
        formData,
        {
            headers: {
                ...formData.getHeaders(), // Use headers from form-data                
                Authorization: process.env.PERSONAL_KEY_CLICKUP,
            }
        }
    );

    const data = resp.data;
    console.log("Uploaded: ", data);

    return data;
});

The challenge seems to be parsing the event object correctly.

Any insights or suggestions from the community would be greatly appreciated

Not sure why you had to write such an extended piece of code to read the body. Body should be already available as req.json(). But anyways, since you’re using Nuxt, I can see that you’ve already mentioned using readBody(). I’m assuming (and you’ve also mentioned) that, that issue is now resolved.

Regarding the other issue, we’d need to see a site and the reproduction steps to answer.

Hey Hrishikesh,

Thank you for your time. I have prepared a copy of the file input field and submit button here: https://terra-feedback.netlify.app/auth/log-in, located below the login form (there’s no need to be logged in to use this functionality).

The readBody() function worked excellently for handling application/json type posts in our project. However, we faced significant challenges when it came to handling multipart/form-data for file uploads. This complexity led us to use Formidable. As I mentioned in my first post, it works great locally and on Heroku, but it fails with a 502 error on Netlify.

Thank you for your time!

For the reproduction your shared, I’m seeing the following error in our logs:

msg="error while processing lambda response" error="invalid status code returned from lambda: 0"

So it seems like the file is being uploaded, processing begins, and your API tries to send a response. However, that response doesn’t include any valid HTTP status code.