{"record":{"id":"024c46f820d8320d","repo":"srbhr/Resume-Matcher","slug":"invalid-file-type-file-content-type-allowed-p","errorCode":null,"errorMessage":"Invalid file type: {file.content_type}. Allowed: PDF, DOC, DOCX","messagePattern":"Invalid file type: (.+?)\\. Allowed: PDF, DOC, DOCX","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"apps/backend/app/routers/resumes.py","lineNumber":639,"sourceCode":"\nALLOWED_TYPES = {\n    \"application/pdf\",\n    \"application/msword\",\n    \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n}\nMAX_FILE_SIZE = 4 * 1024 * 1024  # 4MB\n\n\n@router.post(\"/upload\", response_model=ResumeUploadResponse)\nasync def upload_resume(file: UploadFile = File(...)) -> ResumeUploadResponse:\n    \"\"\"Upload and process a resume file (PDF/DOCX).\n\n    Converts the file to Markdown and stores it in the database.\n    Optionally parses to structured JSON if LLM is configured.\n    \"\"\"\n    # Validate file type\n    if file.content_type not in ALLOWED_TYPES:\n        raise HTTPException(\n            status_code=400,\n            detail=f\"Invalid file type: {file.content_type}. Allowed: PDF, DOC, DOCX\",\n        )\n\n    # Read and validate size\n    content = await file.read()\n    if len(content) > MAX_FILE_SIZE:\n        raise HTTPException(\n            status_code=413,\n            detail=f\"File too large. Maximum size: {MAX_FILE_SIZE // (1024 * 1024)}MB\",\n        )\n\n    if len(content) == 0:\n        raise HTTPException(status_code=400, detail=\"Empty file\")\n\n    # Convert to markdown\n    try:\n        markdown_content = await parse_document(content, file.filename or \"resume.pdf\")","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/backend/app/routers/resumes.py#L621-L657","documentation":"upload_resume validates the multipart file's content_type against the ALLOWED_TYPES set (PDF, DOC, DOCX) before reading it. Any other MIME type — including generic octet-stream — is rejected with HTTP 400 and this detail string naming the accepted types.","triggerScenarios":"POST /api/v1/resumes/upload with a file whose browser-supplied Content-Type is not in ALLOWED_TYPES: e.g. application/octet-stream (common for .docx on Linux/curl), text/plain, image/png, or files uploaded via curl without an explicit -F 'file=@resume.pdf;type=application/pdf'.","commonSituations":"curl/API scripts omitting the MIME type (defaults to octet-stream); exotic office formats (.odt, .rtf, .pages, .key); scanned image uploads; browser MIME sniffing differences across OSes.","solutions":["Re-upload a real PDF or DOCX; when scripting, set the type explicitly: curl -F 'file=@resume.pdf;type=application/pdf'","Convert unsupported formats (ODT/RTF/Pages) to DOCX or PDF first","If your file IS a PDF/DOCX but the client sends octet-stream, fix the client to send the correct Content-Type header"],"exampleFix":"// before: curl sends application/octet-stream for .docx\ncurl -F \"file=@resume.docx\" http://localhost:8000/api/v1/resumes/upload\n// after: explicit MIME type\ncurl -F \"file=@resume.docx;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document\" http://localhost:8000/api/v1/resumes/upload","handlingStrategy":"validation","validationCode":"const ALLOWED = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];\nif (!ALLOWED.includes(file.type)) {\n  throw new Error(`Unsupported type ${file.type}; convert to PDF or DOCX first`);\n}","typeGuard":"const isUploadable = (f: File): boolean =>\n  ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'].includes(f.type);","tryCatchPattern":"try {\n  await api.postForm('/resumes/upload', form);\n} catch (e) {\n  if (e.response?.status === 400 && /Invalid file type/.test(e.response?.data?.detail ?? '')) {\n    showToast('Please upload a PDF or DOCX file');\n  }\n}","preventionTips":["Accept only .pdf/.doc/.docx in the file picker (accept attribute)","When using curl, always set an explicit MIME type: -F 'file=@resume.pdf;type=application/pdf'","Convert ODT/RTF/Pages/images to PDF or DOCX before uploading"],"tags":["http-400","file-upload","mime-type","validation"],"backgroundTag":"unsupported-file-type","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}