medusajs/medusa · error · MedusaError
No file was uploaded for importing
Error message
No file was uploaded for importing
What it means
Thrown by POST /admin/products/import when req.file is unset, i.e. the multipart request carried no actual file part. The route casts req.file to a Multer file and requires it before running importProductsWorkflow.
Source
Thrown at packages/medusa/src/api/admin/products/import/route.ts:19
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "@medusajs/framework/http"
import { HttpTypes } from "@medusajs/framework/types"
import { MedusaError } from "@medusajs/framework/utils"
import { importProductsWorkflow } from "@medusajs/core-flows"
/**
* @deprecated use `POST /admin/products/imports` instead.
*/
export const POST = async (
req: AuthenticatedMedusaRequest<HttpTypes.AdminImportProductRequest>,
res: MedusaResponse<HttpTypes.AdminImportProductResponse>
) => {
const input = req.file as Express.Multer.File
if (!input) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"No file was uploaded for importing"
)
}
const { result, transaction } = await importProductsWorkflow(req.scope).run({
input: {
filename: input.originalname,
fileContent: input.buffer.toString("utf-8"),
},
})
res
.status(202)
.json({ transaction_id: transaction.transactionId, summary: result })
}
View on GitHub (pinned to 5e06e544a2)
Solutions
- Send multipart/form-data with a 'file' field containing the CSV file
- Disable the submit button until a file is selected in the upload UI
- Inspect the actual request in devtools to confirm Content-Type is multipart and the part is named 'file'
Example fix
// before
await sdk.client.fetch("/admin/products/import", { method: "POST", body: JSON.stringify({}) })
// after
const form = new FormData()
form.append("file", new File([csvBlob], "products.csv", { type: "text/csv" }))
await fetch(`${baseUrl}/admin/products/import`, { method: "POST", headers: { Authorization: `Bearer ${token}` }, body: form }) Defensive patterns
Strategy: validation
Validate before calling
if (!(file instanceof File) || file.size === 0) {
throw new Error("Select a non-empty CSV file before importing")
}
const form = new FormData()
form.append("file", file)
await fetch(`${baseUrl}/admin/products/import`, { method: "POST", headers: auth, body: form }) Type guard
const isMultipartFile = (f: unknown): f is File => f instanceof File && f.size > 0
Try / catch
try {
await importProducts(form)
} catch (e: any) {
if (e.statusCode === 400 && /no file/i.test(e.message)) showFilePickerError()
else throw e
} Prevention
- Always send multipart/form-data with part named 'file'
- Disable submit until a file is chosen
- Log the request Content-Type in failing upload code
When it happens
Trigger: Sending the request without multipart/form-data, with the file under the wrong field name (must be 'file'), or with an empty/omitted file part.
Common situations: SDK/fetch clients sending JSON instead of FormData, upload forms where the user did not select a file, proxies stripping multipart bodies, or wrong field naming in custom upload code.
Related errors
- Product not found
- Product with id "${req.params.id}" not found
- Product options are not provided for: [${missingOptionsProdu
- Collection with id "${req.params.id}" not found
- Invite with id: ${id} was not found
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/1086ebf0b1e3c56f.
Report an issue: GitHub.