{"record":{"id":"6063dc3b71a6c3b1","repo":"argoproj/argo-workflows","slug":"failed-to-get-file-from-form","errorCode":null,"errorMessage":"Failed to get file from form: ","messagePattern":"Failed to get file from form: ","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"server/artifacts/artifact_server.go","lineNumber":174,"sourceCode":"\tdefer func() {\n\t\tif r.MultipartForm != nil {\n\t\t\t_ = r.MultipartForm.RemoveAll()\n\t\t}\n\t}()\n\n\t// Parse multipart form (max 32MB in memory, rest on disk)\n\tif parseErr := r.ParseMultipartForm(32 << 20); parseErr != nil {\n\t\tif _, ok := errors.AsType[*http.MaxBytesError](parseErr); ok {\n\t\t\thttp.Error(w, http.StatusText(http.StatusRequestEntityTooLarge), http.StatusRequestEntityTooLarge)\n\t\t\treturn\n\t\t}\n\t\thttp.Error(w, \"Failed to parse multipart form: \"+parseErr.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tfile, header, err := r.FormFile(\"file\")\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to get file from form: \"+err.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\ta.logger.WithFields(logging.Fields{\n\t\t\"filename\": header.Filename,\n\t\t\"size\":     header.Size,\n\t}).Info(ctx, \"Received file for upload\")\n\n\t// Find the artifact in the WorkflowTemplate's arguments.artifacts\n\tvar templateArtifact *wfv1.Artifact\n\tif wfTemplate.Spec.Arguments.Artifacts != nil {\n\t\tfor i := range wfTemplate.Spec.Arguments.Artifacts {\n\t\t\tif wfTemplate.Spec.Arguments.Artifacts[i].Name == artifactName {\n\t\t\t\ttemplateArtifact = &wfTemplate.Spec.Arguments.Artifacts[i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/artifacts/artifact_server.go#L156-L192","documentation":"The artifact upload HTTP endpoint requires a multipart/form-data body containing a file part named exactly \"file\". This error is returned by UploadInputArtifact when r.FormFile(\"file\") fails — the part is missing or named differently. It is a client-side request-shape problem, always returned with HTTP 400.","triggerScenarios":"POSTing to the input-artifact upload endpoint with no part named \"file\"; using a different field name (e.g. \"artifact\", \"upload\", \"data\"); sending JSON or raw bytes instead of multipart/form-data; a client library that streams multipart incorrectly so the part never materializes after ParseMultipartForm.","commonSituations":"Hand-rolled curl/Python/JS clients that use the wrong form field name; users crafting a raw POST in Postman/Insomnia without a file field; SDK version mismatches where the client changed the field name; proxies or gateways that strip or re-encode multipart bodies.","solutions":["Attach the file as a multipart form part with field name exactly \"file\" (e.g. curl -F 'file=@mydata.bin' ...).","Ensure the Content-Type of the request is multipart/form-data with a proper boundary — do not set it manually; let the HTTP client generate it.","If using a custom client, verify with r.FormFile-compatible semantics: the part must be present before the handler parses the form.","Check any intermediary proxy/gateway preserves the multipart body unchanged."],"exampleFix":"// before (wrong field name)\ncurl -X POST -F 'upload=@data.bin' $SERVER/api/v1/workflows/$NS/$WF/input-artifacts/$NAME\n// after\ncurl -X POST -F 'file=@data.bin' $SERVER/api/v1/workflows/$NS/$WF/input-artifacts/$NAME","handlingStrategy":"validation","validationCode":"const fd = new FormData();\nif (!file) throw new Error('upload aborted: no file selected');\nfd.append('file', file, file.name); // field name MUST be 'file'\n// sanity check before send:\nif (![...fd.keys()].includes('file')) throw new Error('form missing \"file\" part');","typeGuard":null,"tryCatchPattern":"try {\n  const res = await fetch(url, { method: 'POST', body: fd }); // let client set multipart Content-Type\n  if (res.status === 400) throw new Error('Server rejected form: ' + await res.text());\n} catch (e) { /* fix field name / Content-Type and retry once */ }","preventionTips":["Always use the field name 'file' when appending to FormData.","Never set the multipart Content-Type header manually; let the client generate the boundary.","Smoke-test uploads with curl -F 'file=@...' before wiring custom clients.","Log the request body shape client-side when developing new upload integrations."],"tags":["http","multipart","bad-request","artifact-upload"],"backgroundTag":"missing-multipart-form-field","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}