{"record":{"id":"5279b92ca0331d1c","repo":"HKUDS/DeepTutor","slug":"sanitized-filename-is-not-a-valid-zip-archive","errorCode":null,"errorMessage":"'{sanitized_filename}' is not a valid zip archive.","messagePattern":"'(.+?)' is not a valid zip archive\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"deeptutor/api/routers/knowledge.py","lineNumber":290,"sourceCode":"                        status_code=400,\n                        detail=(\n                            f\"Archive '{sanitized_filename}' exceeds maximum size limit of \"\n                            f\"{format_bytes_human_readable(max_size)}\"\n                        ),\n                    )\n                tmp.write(chunk)\n\n        try:\n            result = safe_extract_zip(\n                tmp_path, target_dir, allowed_extensions=allowed_extensions or set()\n            )\n        except ArchiveTooLargeError as exc:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"Rejected archive '{sanitized_filename}': {exc}\",\n            ) from exc\n        except zipfile.BadZipFile as exc:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"'{sanitized_filename}' is not a valid zip archive.\",\n            ) from exc\n\n        if not result.extracted:\n            raise HTTPException(\n                status_code=400,\n                detail=f\"Archive '{sanitized_filename}' contained no supported files.\",\n            )\n        return result.extracted\n    finally:\n        if tmp_path is not None:\n            tmp_path.unlink(missing_ok=True)\n\n\n# Folder organization is purely a human-facing layout: folders are real\n# subdirectories under ``raw/`` (no manifest, no retrieval effect). These\n# helpers keep user-supplied relative paths safe before they touch the FS.","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/api/routers/knowledge.py#L272-L308","documentation":"Raised by _save_zip_archive when Python's zipfile module throws BadZipFile while opening/extracting an uploaded archive. The file's name/extension suggests a .zip but its content is corrupt, truncated, or not a zip at all (e.g. a renamed file or an interrupted upload). The router converts it to HTTP 400 so the client knows the payload itself is invalid.","triggerScenarios":"POST to the knowledge-base upload endpoint with a file whose extension triggers zip handling but whose bytes fail zipfile.ZipFile parsing — corrupt download, HTML error page saved as .zip, multipart upload truncated by a proxy, or double-compressed/encrypted archive.","commonSituations":"Client uploads a file renamed to .zip; archive corrupted during transfer; a 0-byte zip from a failed disk write; test fixtures generating invalid zips.","solutions":["Re-download or regenerate the archive and verify it opens locally with `unzip -t file.zip`","Check the upload pipeline (proxy body limits, multipart handling) is not truncating the file","If the file is not meant to be an archive, upload it with its real extension so it bypasses zip handling","Verify Content-Length matches the actual file size before uploading"],"exampleFix":"# before\nfiles = {'file': open('notes.zip','rb')}  # notes.zip is actually a PDF\nrequests.post(url, files=files)\n# after\nimport zipfile\nwith open('notes.zip','rb') as f:\n    assert zipfile.is_zipfile(f), 'not a zip'\nrequests.post(url, files=files)","handlingStrategy":"validation","validationCode":"import zipfile\n\ndef is_valid_zip(path):\n    with open(path,'rb') as f:\n        return zipfile.is_zipfile(f) and zipfile.ZipFile(f).testzip() is None","typeGuard":null,"tryCatchPattern":"try: resp = upload(files)\nexcept HTTPError as e:\n    if e.response.status_code == 400 and 'not a valid zip archive' in e.response.text(): repair_and_retry()\n    else: raise","preventionTips":["Run zipfile.is_zipfile() before uploading","Verify archive integrity with testzip() client-side","Confirm uploads complete (match Content-Length) before submitting"],"tags":["zip","upload","bad-file","http-400"],"backgroundTag":"invalid-archive-upload","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}