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

  1. Send exactly one file under the 'file' field per request.
  2. If multiple CSVs must be imported, concatenate them client-side or issue sequential single-file requests.
  3. Remove the `multiple` attribute from the file input in the uploader component.
  4. 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

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


AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12). Data as JSON: /api/errors/9b8d52beebf0412b. Report an issue: GitHub.