medusajs/medusa · error · MedusaError
No file provided
Error message
No file provided
What it means
The local file service's upload rejects a falsy file argument with INVALID_DATA before doing anything else — there is no file object to read a filename or stream from.
Source
Thrown at packages/modules/providers/file-local/src/services/local-file.ts:62
constructor(_, options: LocalFileServiceOptions) {
super()
this.uploadDir_ = options?.upload_dir || path.join(process.cwd(), "static")
// Since there is no way to serve private files through a static server, we simply place them in `static`.
// This means that the files will be available publicly if the filename is known. Since the local file provider
// is for development only, this shouldn't be an issue. If you really want to use it in production (and you shouldn't)
// You can change the private upload dir to `/private` but none of the functionalities where you use a presigned URL will work.
this.privateUploadDir_ =
options?.private_upload_dir || path.join(process.cwd(), "static")
this.backendUrl_ = options?.backend_url || "http://localhost:9000/static"
}
async upload(
file: FileTypes.ProviderUploadFileDTO
): Promise<FileTypes.ProviderFileResultDTO> {
if (!file) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, `No file provided`)
}
if (!file.filename) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`No filename provided`
)
}
const parsedFilename = path.parse(file.filename)
const baseDir =
file.access === "public" ? this.uploadDir_ : this.privateUploadDir_
await this.ensureDirExists(baseDir, parsedFilename.dir)
const fileKey = path.join(
parsedFilename.dir,
// We prepend "private" to the file key so deletions and presigned URLs can know which folder to look into
`${file.access === "public" ? "" : "private-"}${Date.now()}-${View on GitHub (pinned to 5e06e544a2)
Solutions
- Check the multipart/form-data parse result before delegating: if no file part exists, return a 400 instead of calling upload.
- On the client, ensure the file field name matches what the server/middleware expects and that Content-Type is multipart/form-data.
- In route code, validate file presence before invoking the file service.
Example fix
// before
const result = await fileService.upload(req.body.file) // undefined when no file part
// after
if (!req.file) return res.status(400).json({ message: "No file provided" })
const result = await fileService.upload(req.file) Defensive patterns
Strategy: validation
Validate before calling
if (!file) {
return res.status(400).json({ message: "No file provided" })
}
await fileService.upload(file) Type guard
const isUploadFileDTO = (f: unknown): f is FileTypes.ProviderUploadFileDTO => !!f && typeof f === "object" && typeof (f as any).filename === "string"
Try / catch
try { await fileService.upload(file) } catch (e) { if (e instanceof MedusaError && /No file provided/.test(e.message)) { res.status(400).json({ message: e.message }); return } throw e } Prevention
- Validate the multipart parse result before delegating to the file service.
- Set client-side required-field checks on file inputs.
- Return early 400s for empty bodies rather than letting the service throw.
When it happens
Trigger: Calling provider.upload(undefined/null), typically because an upstream form-parse failed or an empty multipart body was submitted.
Common situations: An upload API route forwarding req.body when the client sent no file; tests calling the service directly with no argument; a refactor that renamed the variable holding the parsed file.
Related errors
- No filename provided
- --paths must be a directory - ${additionalPath}
- --base must be a file - ${baseFile}
- insufficient_inventory
- not_found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/0b2d1a0c997226b9.
Report an issue: GitHub.