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
- Convert the source data to CSV before uploading (Excel: File > Save As > CSV UTF-8).
- When using FormData.append in JS, pass the filename explicitly: form.append('file', blob, 'annotations.csv').
- Strip query strings or fragments from the filename before upload.
- 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
- Always pass a filename as the third arg to FormData.append.
- Restrict the file input with accept='.csv'.
- Convert Excel/TSV exports to CSV before upload.
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.