langgenius/dify · error · ValueError

Invalid file type. Only CSV files are allowed

Error message

Invalid file type. Only CSV files are allowed

What it means

Raised by AnnotationBatchImportApi.post when the uploaded file's filename is missing (None/empty) or does not end with '.csv' (case-insensitive). This is a raw Python ValueError, not a BaseHTTPException, so it is translated to a 400 by Flask's default error handler rather than Dify's structured error envelope. Only CSV files are accepted for annotation batch import.

Source

Thrown at api/controllers/console/app/annotation.py:478

    @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. "
                f"Please reduce the file size and try again.",
            )

        if file_size == 0:
            raise ValueError("The uploaded file is empty")

        return dump_response(

View on GitHub (pinned to ef8544b173)

Solutions

  1. Convert the source data to CSV before uploading (Excel: File > Save As > CSV UTF-8).
  2. When using FormData.append in JS, pass the filename explicitly: form.append('file', blob, 'annotations.csv').
  3. Strip query strings or fragments from the filename before upload.
  4. If your pipeline produces another format, add a pre-upload conversion step.

Example fix

// before
form.append('file', blob);

// after
form.append('file', blob, 'annotations.csv');
Defensive patterns

Strategy: validation

Validate before calling

function assertCsv(file) {
  if (!file || !file.name) throw new Error('File must have a name');
  if (!file.name.toLowerCase().endsWith('.csv')) throw new Error('Only .csv files are accepted');
  return file;
}

Type guard

const isCsv = (file) => !!file && !!file.name && file.name.toLowerCase().endsWith('.csv');

Try / catch

try { await fetch(url, { method: 'POST', body: form }); }
catch (e) { if (/Invalid file type/.test(e.message)) alert('Please upload a .csv file.'); }

Prevention

When it happens

Trigger: Uploading .xlsx, .tsv, .txt, .json, or any non-.csv extension; uploading a file whose filename attribute is empty (some clients omit Content-Disposition filename); uploading a Blob without a filename in JS FormData.

Common situations: User exports Excel instead of CSV; frontend creates a Blob and appends without a third filename argument (form.append('file', blob) — no filename); macOS hiding the extension causes the saved file to be named 'annotations' with no suffix.

Related errors


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