langgenius/dify · error · NotFound
UploadFile not found.
Error message
UploadFile not found.
What it means
Raised by the segment batch-import POST endpoint when the supplied upload_file_id does not resolve to a row in the UploadFile table. The controller verifies dataset and document first, then loads the UploadFile by id; a None result triggers flask-restx NotFound (HTTP 404). It means the file referenced by the request body was never uploaded, was deleted, or does not belong to the tenant scope the query sees.
Source
Thrown at api/controllers/console/datasets/datasets_segments.py:647
dataset_id: UUID,
document_id: UUID,
):
# check dataset
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,View on GitHub (pinned to ef8544b173)
Solutions
- Re-run the file upload and capture the returned upload_file_id, then re-send the batch_import request with that fresh id.
- Confirm the upload_file_id belongs to the same tenant by checking the upload history endpoint before submitting the import.
- If the file was intentionally deleted, upload a new CSV and use its id.
Example fix
// before
POST .../segments/batch_import body: {"upload_file_id": "<stale id>"}
// after
1) POST .../files/upload (multipart: the .csv) -> {"id": "<new_id>"}
2) POST .../segments/batch_import body: {"upload_file_id": "<new_id>"} Defensive patterns
Strategy: validation
Validate before calling
// Before POSTing batch_import, verify the upload file id resolves to a CSV.
async function safeBatchImport(uploadFileId, ids) {
const fileMeta = await fetch(`/console/api/files/upload/${uploadFileId}`).then(r => r.ok ? r.json() : null);
if (!fileMeta) throw new Error('upload_file_id is invalid; re-upload the CSV first');
return fetch(`/console/api/datasets/${ids.dataset}/documents/${ids.document}/segments/batch_import`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({upload_file_id: uploadFileId}),
});
} Type guard
function isValidUploadFileId(id) {
return typeof id === 'string' && /^[0-9a-fA-F-]{36}$/.test(id) && id !== '00000000-0000-0000-0000-000000000000';
} Try / catch
try {
await batchImport(uploadFileId, ids);
} catch (e) {
if (e.status === 404 && /UploadFile not found/.test(e.message)) {
// re-upload then retry once with the new id
const fresh = await uploadCsv(file);
await batchImport(fresh.id, ids);
} else throw e;
} Prevention
- Capture and store the upload_file_id from the upload response immediately, do not hardcode.
- Run the import right after the upload to avoid background cleanup removing the file.
- Confirm the id belongs to the same tenant before submitting.
When it happens
Trigger: POST /console/api/datasets/{dataset_id}/documents/{document_id}/segments/batch_import with a Body.upload_file_id that does not exist in the UploadFile table. Common when the upload step returns an id but it has since been removed, when an id from a different workspace is reused, or when the frontend sends the field as null/empty after a failed upload.
Common situations: Uploading a CSV through the file-upload endpoint, then waiting long enough that the file is cleaned up before the import POST fires; copy-pasting an upload_file_id from another tenant; the upload step silently failed and returned no id while the UI still submits.
Related errors
- The job does not exist.
- Dataset not found.
- Document not found.
- API template not found.
- export response missing data field
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/af1f2d99d6ba33a5.
Report an issue: GitHub.