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 after the UploadFile row is confirmed but its stored name is empty or does not end in .csv (case-insensitive). The batch segment importer is CSV-only, so any other extension or a file with no name is rejected with ValueError. This typically surfaces as an HTTP 400/500 depending on the framework's ValueError handler rather than a clean NotFound.

Source

Thrown at api/controllers/console/datasets/datasets_segments.py:651

        dataset_id_str = str(dataset_id)
        dataset = DatasetService.get_dataset(dataset_id_str, session)
        if not dataset:
            raise NotFound("Dataset not found.")
        # check document
        document_id_str = str(document_id)
        document = DocumentService.get_document(dataset_id_str, document_id_str, session=session)
        if not document:
            raise NotFound("Document not found.")

        upload_file_id = req_data.upload_file_id

        upload_file = session.scalar(select(UploadFile).where(UploadFile.id == upload_file_id).limit(1))
        if not upload_file:
            raise NotFound("UploadFile not found.")

        # check file type
        if not upload_file.name or not upload_file.name.lower().endswith(".csv"):
            raise ValueError("Invalid file type. Only CSV files are allowed")

        try:
            # async job
            job_id = str(uuid.uuid4())
            indexing_cache_key = f"segment_batch_import_{job_id}"
            # send batch add segments task
            redis_client.setnx(indexing_cache_key, "waiting")
            batch_create_segment_to_index_task.delay(
                job_id,
                upload_file_id,
                dataset_id_str,
                document_id_str,
                current_tenant_id,
                current_user.id,
            )
        except Exception as e:
            return {"error": str(e)}, 500
        return dump_response(SegmentBatchImportStatusResponse, {"job_id": job_id, "job_status": "waiting"}), 200

View on GitHub (pinned to ef8544b173)

Solutions

  1. Re-upload the data as a .csv file (with the .csv extension in the filename) and pass the new upload_file_id.
  2. Verify the extension before submitting: assert the stored UploadFile.name ends with .csv.
  3. If you must import non-CSV data, convert it to CSV first; this endpoint does not accept other formats.

Example fix

// before
upload:  data.xlsx   -> {"upload_file_id": "<id>"}
// after
convert data.xlsx -> data.csv
upload data.csv   -> {"upload_file_id": "<id>"}
POST .../segments/batch_import {"upload_file_id": "<id>"}
Defensive patterns

Strategy: validation

Validate before calling

function isCsvFileName(name) {
  return typeof name === 'string' && name.toLowerCase().endsWith('.csv');
}
// client-side: block the submit unless isCsvFileName(file.name)

Type guard

const isCsvFile = (file) => file instanceof File && /\.csv$/i.test(file.name);

Try / catch

if (!isCsvFileName(uploadName)) {
  // prompt user to provide a .csv file, do not call the API
} else {
  await batchImport(uploadFileId, ids);
}

Prevention

When it happens

Trigger: POST .../segments/batch_import with an upload_file_id whose stored name is e.g. data.xlsx, segments.json, or empty. Also triggered when an older file record has a null/None name.

Common situations: User drops a non-CSV file into the batch import dialog; a programmatic caller reuses a generic document upload for the import; migration/import left an UploadFile row with a blank name.

Related errors


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