{"record":{"id":"01048da901b9920d","repo":"theonedev/onedev","slug":"file-name-not-found-in-content-disposition-header","errorCode":null,"errorMessage":"File name not found in content disposition header of uploaded file","messagePattern":"File name not found in content disposition header of uploaded file","errorType":"http","errorClass":"ClientException","httpStatus":400,"severity":"error","filePath":"server-plugin/server-plugin-pack-pypi/src/main/java/io/onedev/server/plugin/pack/pypi/PypiPackHandler.java","lineNumber":143,"sourceCode":"\t\t\t\t\t\t\t\tattributes.remove(\"blake2_256_digest\");\n\t\t\t\t\t\t\t\tattributes.remove(\":action\");\n\t\t\t\t\t\t\t\tattributes.remove(\"protocol_version\");\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\tLockUtils.run(getLockName(projectId, name), () -> transactionService.run(() -> {\n\t\t\t\t\t\t\t\t\tvar project = checkProject(projectId, true);\n\t\t\t\t\t\t\t\t\tvar contentDisposition = item.getHeaders().getHeader(\"content-disposition\"); \n\t\t\t\t\t\t\t\t\tif (contentDisposition == null)\n\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_BAD_REQUEST, \"Content disposition header not found in uploaded file\");\n\t\t\t\t\t\t\t\t\tString fileName = null;\n\t\t\t\t\t\t\t\t\tfor (var field: Splitter.on(\";\").omitEmptyStrings().trimResults().split(contentDisposition)) {\n\t\t\t\t\t\t\t\t\t\tif (field.startsWith(\"filename=\")) {\n\t\t\t\t\t\t\t\t\t\t\tfileName = field.substring(\"filename=\".length() + 1);\n\t\t\t\t\t\t\t\t\t\t\tfileName = fileName.substring(0, fileName.length() - 1);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (fileName == null) \n\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_BAD_REQUEST, \"File name not found in content disposition header of uploaded file\");\n\n\t\t\t\t\t\t\t\t\tvar packBlobId = packBlobService.uploadBlob(projectId, is, sha256Hash);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tif (packBlobId == null)\n\t\t\t\t\t\t\t\t\t\tthrow new ClientException(SC_BAD_REQUEST, \"Digest mismatch\");\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tPypiData data;\n\t\t\t\t\t\t\t\t\tvar pack = packService.findByNameAndVersion(project, TYPE, name, version);\n\t\t\t\t\t\t\t\t\tif (pack == null) {\n\t\t\t\t\t\t\t\t\t\tpack = new Pack();\n\t\t\t\t\t\t\t\t\t\tpack.setType(TYPE);\n\t\t\t\t\t\t\t\t\t\tpack.setName(name);\n\t\t\t\t\t\t\t\t\t\tpack.setVersion(version);\n\t\t\t\t\t\t\t\t\t\tpack.setProject(project);\n\t\t\t\t\t\t\t\t\t\tdata = new PypiData(attributes, new LinkedHashMap<>());\n\t\t\t\t\t\t\t\t\t\tpack.setData(data);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tdata = (PypiData) pack.getData();\n\t\t\t\t\t\t\t\t\t}","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-plugin/server-plugin-pack-pypi/src/main/java/io/onedev/server/plugin/pack/pypi/PypiPackHandler.java#L125-L161","documentation":"The handler parses the Content-Disposition header of the uploaded file part to extract the filename= parameter. If the header exists but contains no filename field (or it is empty), a ClientException (HTTP 400) is thrown.","triggerScenarios":"Multipart file part with a Content-Disposition like 'form-data; name=\"file\"' but no filename=\"...\" attribute, or an empty filename value.","commonSituations":"Client libraries that submit form fields without a filename attribute for file parts; template-generated requests where the filename variable is empty; programmatic multipart builders that omit filename.","solutions":["Ensure the file part includes filename= in its Content-Disposition: curl -F \"file=@actual-file.whl\" does this automatically.","If constructing the request manually, add filename=\"pkg.whl\" to the part header.","Log/inspect the Content-Disposition header of the failing request to confirm what the client actually sent."],"exampleFix":"// before\nContent-Disposition: form-data; name=\"file\"\n// after\nContent-Disposition: form-data; name=\"file\"; filename=\"mypkg-1.0.0-py3-none-any.whl\"","handlingStrategy":"validation","validationCode":"# ensure filename is included in the file part\nfiles = {'file': ('pkg-1.0.0.whl', fh)}  # explicit tuple with filename","typeGuard":null,"tryCatchPattern":"if resp.status_code == 400 and 'File name not found' in resp.text:\n    raise RuntimeError('Add filename= to the multipart part')","preventionTips":["Pass an explicit filename in file-upload helpers rather than relying on defaults.","Avoid programmatic multipart builders that omit filename on file parts.","Log outgoing headers when debugging uploads."],"tags":["pypi","http-400","multipart","filename"],"backgroundTag":"missing-required-argument","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}