Upload file API stopped working - middleware issue
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #46~20.04.1-Ubuntu SMP Thu Jul 14 15:20:17 UTC 2022
Binaries:
Node: 16.16.0
npm: 8.1.2
Yarn: 1.22.17
pnpm: N/A
Relevant packages:
next: 12.2.4
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
Simply the API to upload the file stopped working. The request hangs and there is no response

The request does not reach the breakpoint on the API line 81 if (!request.file) {
when I remove the form-data params the API is called and of course, I get File was not provided
Expected Behavior
It should just work like before
Link to reproduction
/
To Reproduce
To reproduce here the API upload.tsx
/* eslint-disable unicorn/no-null */
import * as mime from 'mime-types'
import multer from 'multer'
import { NextApiRequest, NextApiResponse } from 'next'
export const config = {
api: {
bodyParser: false, // Disallow body parsing, consume as stream
},
}
interface NextApiRequestExtended extends NextApiRequest {
file: any
files: any
}
const upload = multer({
storage: multer.diskStorage({
destination: (request, file, callback) => {
const { isProjectPic } = request.query
const destinationPath =
isProjectPic === 'true'
? `./public/uploads/project`
: `./public/uploads/profile`
callback(null, destinationPath)
},
filename: (request, file, callback) => {
const extension = mime.extension(file.mimetype)
if (typeof extension === `string`) {
const fileNames = file.originalname.split('.', 1)
const { userId } = request.query
if (fileNames.length > 0) {
const fileName = fileNames[0]
.toLowerCase()
.replace(/\s/g, '-')
// eslint-disable-next-line unicorn/prefer-spread
.concat('-', userId ? (userId as string) : '', '.', extension)
callback(null, fileName)
}
}
callback(null, file.originalname)
},
}),
// 1MB
limits: { fileSize: 1 * 1024 * 1024 },
fileFilter: (request, file, callback) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
callback(null, true)
} else {
return callback(new Error('Invalid mime type'))
}
},
})
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(
request: NextApiRequestExtended,
response: NextApiResponse,
function_: any,
) {
return new Promise((resolve, reject) => {
function_(request, response, (result: any) => {
if (result instanceof Error) {
return reject(result)
}
return resolve(result)
})
})
}
const handler = async (
request: NextApiRequestExtended,
response: NextApiResponse,
) => {
try {
await runMiddleware(request, response, upload.single('image-upload'))
if (!request.file) {
return response.status(404).end('File was not provided')
}
const file = request.file
return response.status(200).send({
filename: file.filename,
size: file.size,
path: file.path,
})
} catch (error: any) {
return response.status(404).end(error.message)
}
}
export default handler
I have middleware.tsx file, when I remove it the upload works.
What it's wrong with the middleware implementation?
// middleware.ts
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
// https://nextjs.org/docs/messages/middleware-upgrade-guide
const PUBLIC_FILE = /\.(.*)$/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function middleware(request: NextRequest) {
const shouldHandleLocale =
!PUBLIC_FILE.test(request.nextUrl.pathname) &&
!request.nextUrl.pathname.includes('/api/') &&
request.nextUrl.locale === 'default'
return shouldHandleLocale
? NextResponse.redirect(`/en${request.nextUrl.href}`)
: undefined
}
maybe related to https://github.com/vercel/next.js/issues/39262
It happens exactly the same to me!
In my case I have the same issue
I have the same exact issue
Same here
I have the same problem with a POST request with a payload of 50Kb
Edit:
Fixed skipping api requests in middleware, you can add the following code to middleware.js
export const config = {
matcher: '/((?!api\/).*)',
}
It should be works now.
Check: https://github.com/vercel/next.js/issues/36497#issuecomment-1271419308 🙂
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.