langgenius/dify · error · TooManyFilesError
too_many_files
too_many_files
Error message
Only one file is allowed.
What it means
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').
Source
Thrown at api/controllers/console/app/annotation.py:471
@console_ns.response(429, "Too many requests or concurrent imports")
@setup_required
@login_required
@account_initialization_required
@cloud_edition_billing_resource_check("annotation")
@annotation_import_rate_limit
@annotation_import_concurrency_limit
@edit_permission_required
@rbac_permission_required(RBACResourceScope.APP, RBACPermission.APP_EDIT)
@with_session
def post(self, session: Session, app_id: UUID):
from configs import dify_config
# check file
if "file" not in request.files:
raise NoFileUploadedError()
if len(request.files) > 1:
raise TooManyFilesError()
# get file from request
file = request.files["file"]
# check file type
if not file.filename or not file.filename.lower().endswith(".csv"):
raise ValueError("Invalid file type. Only CSV files are allowed")
# Check file size before processing
file.stream.seek(0, 2) # Seek to end of file
file_size = file.stream.tell()
file.stream.seek(0) # Reset to beginning
max_size_bytes = dify_config.ANNOTATION_IMPORT_FILE_SIZE_LIMIT * 1024 * 1024
if file_size > max_size_bytes:
abort(
413,
f"File size exceeds maximum limit of {dify_config.ANNOTATION_IMPORT_FILE_SIZE_LIMIT}MB. "View on GitHub (pinned to ef8544b173)
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.
Example fix
// before
for (const f of files) form.append('file', f);
await fetch(url, { method: 'POST', body: form });
// after
for (const f of files) {
const single = new FormData();
single.append('file', f);
await fetch(url, { method: 'POST', body: single });
} Defensive patterns
Strategy: validation
Validate before calling
function assertSingleFile(fileList) {
if (!fileList || fileList.length === 0) throw new Error('No file selected');
if (fileList.length > 1) throw new Error('Only one CSV file is allowed per import');
return fileList[0];
} Type guard
const isExactlyOneFile = (files) => Array.isArray(files) && files.length === 1;
Try / catch
try { await fetch(url, { method: 'POST', body: form }); }
catch (e) { if (e.code === 'too_many_files') alert('Select one file only.'); } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- no_file_uploaded
- Invalid file type. Only CSV files are allowed
- The uploaded file is empty
- no_audio_uploaded
- unsupported_audio_type
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/9b8d52beebf0412b.
Report an issue: GitHub.