{"record":{"id":"9b8d52beebf0412b","repo":"langgenius/dify","slug":"too-many-files-9b8d52","errorCode":"too_many_files","errorMessage":"Only one file is allowed.","messagePattern":"Only one file is allowed\\.","errorType":"error_code","errorClass":"TooManyFilesError","httpStatus":400,"severity":"error","filePath":"api/controllers/console/app/annotation.py","lineNumber":471,"sourceCode":"    @console_ns.response(429, \"Too many requests or concurrent imports\")\n    @setup_required\n    @login_required\n    @account_initialization_required\n    @cloud_edition_billing_resource_check(\"annotation\")\n    @annotation_import_rate_limit\n    @annotation_import_concurrency_limit\n    @edit_permission_required\n    @rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)\n    @with_session\n    def post(self, session: Session, app_id: UUID):\n        from configs import dify_config\n\n        # check file\n        if \"file\" not in request.files:\n            raise NoFileUploadedError()\n\n        if len(request.files) > 1:\n            raise TooManyFilesError()\n\n        # get file from request\n        file = request.files[\"file\"]\n\n        # check file type\n        if not file.filename or not file.filename.lower().endswith(\".csv\"):\n            raise ValueError(\"Invalid file type. Only CSV files are allowed\")\n\n        # Check file size before processing\n        file.stream.seek(0, 2)  # Seek to end of file\n        file_size = file.stream.tell()\n        file.stream.seek(0)  # Reset to beginning\n\n        max_size_bytes = dify_config.ANNOTATION_IMPORT_FILE_SIZE_LIMIT * 1024 * 1024\n        if file_size > max_size_bytes:\n            abort(\n                413,\n                f\"File size exceeds maximum limit of {dify_config.ANNOTATION_IMPORT_FILE_SIZE_LIMIT}MB. \"","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/app/annotation.py#L453-L489","documentation":"Raised by POST /console/apps/{app_id}/annotations/batch-import when request.files contains more than one entry. The endpoint only accepts a single CSV, so len(request.files) > 1 raises TooManyFilesError (400, error_code 'too_many_files').","triggerScenarios":"Submitting the batch-import form with multiple file inputs populated, or a single input configured to accept multiple files (e.g., <input type='file' multiple>) where the user selects more than one. Repeated 'file' field in cURL (-F 'file=@a.csv' -F 'file=@b.csv') also triggers it.","commonSituations":"Uploader UI built with `multiple` attribute accidentally left on; batch tooling that tries to upload a folder of CSVs in one request; test harnesses attaching both a real file and a dummy file.","solutions":["Send exactly one file under the 'file' field per request.","If multiple CSVs must be imported, concatenate them client-side or issue sequential single-file requests.","Remove the `multiple` attribute from the file input in the uploader component.","Loop over files in the client and call the endpoint once per file rather than once for all."],"exampleFix":"// before\nfor (const f of files) form.append('file', f);\nawait fetch(url, { method: 'POST', body: form });\n\n// after\nfor (const f of files) {\n  const single = new FormData();\n  single.append('file', f);\n  await fetch(url, { method: 'POST', body: single });\n}","handlingStrategy":"validation","validationCode":"function assertSingleFile(fileList) {\n  if (!fileList || fileList.length === 0) throw new Error('No file selected');\n  if (fileList.length > 1) throw new Error('Only one CSV file is allowed per import');\n  return fileList[0];\n}","typeGuard":"const isExactlyOneFile = (files) => Array.isArray(files) && files.length === 1;","tryCatchPattern":"try { await fetch(url, { method: 'POST', body: form }); }\ncatch (e) { if (e.code === 'too_many_files') alert('Select one file only.'); }","preventionTips":["Remove the `multiple` attribute from the file input for this endpoint.","Validate selection count in the UI before submit.","Issue one request per file when batch uploads are needed."],"tags":["annotations","file-upload","multipart","console-api","validation"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}