next.js: TypeError: req.on is not a function

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 21.6.0: Thu Mar  9 20:08:59 PST 2023; root:xnu-8020.240.18.700.8~1/RELEASE_X86_64
    Binaries:
      Node: 16.19.0
      npm: 8.19.3
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.3.2-canary.7
      eslint-config-next: 13.3.1
      react: 18.2.0
      react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true)

Link to the code that reproduces this issue

none

To Reproduce

    export const api = { bodyParser: false }
    
    export async function POST(req) {
      const token = await getToken({ req })
    
      if (token) {
        const data = await new Promise((resolve, reject) => {
          const form = new IncomingForm({ multiples: true })
          form.parse(req, (err, fields, files) => {
            if (err) return reject(err)
            resolve({ fields, files })
          })
        })
    
        const { fields } = data
    
        console.log(fields)
    
        if (fields.approved_flag === 'true') {
          NextResponse.json({ message: 'Ok' })
        } else {
          NextResponse.json({ message: 'You have to confirm first' }, { status: 400 })
        }
      } else {
        return NextResponse.json({ message: 'Token not valid or expired' }, { status: 400 })
      }
    }

Describe the Bug

error - TypeError: req.on is not a function
    at IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/src/Formidable.js:182:13)
    at POST.data (webpack-internal:///(sc_server)/./app/api/shipping/update/route.js:28:18)
    at new Promise (<anonymous>)
    at POST (webpack-internal:///(sc_server)/./app/api/shipping/update/route.js:24:28)
    at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:233:33)

Working fine with /pages, but not /app

Expected Behavior

I think the request missing function

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 10
  • Comments: 21 (2 by maintainers)

Most upvoted comments

So after spending some time on this it seems like Nextjs 13 API handlers handle form data for you. I found this example using directus. I know this isn’t a direct answer to using formidable but maybe it helps someone in the future?

The tl;dr is that you can now access formdata through the request.formdata

export async function POST(request: Request) {
  const formData = await request.formData();
  const file = formData.get('file');
  console.log("form data", formData, file);
}

Hope this helps someone

Okay, but how to fix it so ? I encountered the same issue

same issue here, using next: 13.4.2, and formidable

I’m having the same issue. Is there any way to get req as NextApiRequest in Next 13?

same for me. Also

import formidable from 'formidable'

const form = formidable()
new Promise((resolve, reject) => {
    form.parse(request, (err, fields, files) => {
      if (err) reject(err)
      resolve({ fields, files })
    })
  })

formidable@v3.2.5

typescript error is: Argument of type NextRequest is not assignable to parameter of type IncomingMessage.

TypeError: req.on is not a function
    at IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/src/Formidable.js:182:13)

any up ?

Would be good to know the official recommendation for how to listen to various events that are typically available on the NodeJS instance of the “req” instance.

One use-case is to listen to closed connection when a streaming socket is closed. Funny enough, documentation does provide an example of streaming data from a Route, however fails to address a situation if a stream is interrupted, or if you are streaming to multiple users, and one of the users disconnects.

Route Handler gives you a Request instance, not a Node.js-like NextApiRequest which is based on IncomingMessage, what Formidable seem to expect, so this is not a Next.js bug.

So after spending some time on this it seems like Nextjs 13 API handlers handle form data for you. I found this example using directus. I know this isn’t a direct answer to using formidable but maybe it helps someone in the future?

The tl;dr is that you can now access formdata through the request.formdata

export async function POST(request: Request) {
  const formData = await request.formData();
  const file = formData.get('file');
  console.log("form data", formData, file);
}

Hope this helps someone

This solved my issue. It seems we don’t require formidable now as nextjs is handling it out of box. Thanks mate…!!

I also encountered the same event.

This is not a good solution, but it seems to be handled by API Route by creating a file in /pages/api/* even for App Router enabled applications.

I have confirmed this workaround with Next 13.4.2 .

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Pro
    Binaries:
      Node: 18.16.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant packages:
      next: 13.4.2
      eslint-config-next: 13.4.2
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.0.4