{"record":{"id":"af1f2d99d6ba33a5","repo":"langgenius/dify","slug":"uploadfile-not-found","errorCode":null,"errorMessage":"UploadFile not found.","messagePattern":"UploadFile not found\\.","errorType":"http","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"api/controllers/console/datasets/datasets_segments.py","lineNumber":647,"sourceCode":"        dataset_id: UUID,\n        document_id: UUID,\n    ):\n        # check dataset\n        dataset_id_str = str(dataset_id)\n        dataset = DatasetService.get_dataset(dataset_id_str, session)\n        if not dataset:\n            raise NotFound(\"Dataset not found.\")\n        # check document\n        document_id_str = str(document_id)\n        document = DocumentService.get_document(dataset_id_str, document_id_str, session=session)\n        if not document:\n            raise NotFound(\"Document not found.\")\n\n        upload_file_id = req_data.upload_file_id\n\n        upload_file = session.scalar(select(UploadFile).where(UploadFile.id == upload_file_id).limit(1))\n        if not upload_file:\n            raise NotFound(\"UploadFile not found.\")\n\n        # check file type\n        if not upload_file.name or not upload_file.name.lower().endswith(\".csv\"):\n            raise ValueError(\"Invalid file type. Only CSV files are allowed\")\n\n        try:\n            # async job\n            job_id = str(uuid.uuid4())\n            indexing_cache_key = f\"segment_batch_import_{job_id}\"\n            # send batch add segments task\n            redis_client.setnx(indexing_cache_key, \"waiting\")\n            batch_create_segment_to_index_task.delay(\n                job_id,\n                upload_file_id,\n                dataset_id_str,\n                document_id_str,\n                current_tenant_id,\n                current_user.id,","sourceCodeStart":629,"sourceCodeEnd":665,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/datasets/datasets_segments.py#L629-L665","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nPOST .../segments/batch_import  body: {\"upload_file_id\": \"<stale id>\"}\n// after\n1) POST .../files/upload  (multipart: the .csv)  ->  {\"id\": \"<new_id>\"}\n2) POST .../segments/batch_import  body: {\"upload_file_id\": \"<new_id>\"}","handlingStrategy":"validation","validationCode":"// Before POSTing batch_import, verify the upload file id resolves to a CSV.\nasync function safeBatchImport(uploadFileId, ids) {\n  const fileMeta = await fetch(`/console/api/files/upload/${uploadFileId}`).then(r => r.ok ? r.json() : null);\n  if (!fileMeta) throw new Error('upload_file_id is invalid; re-upload the CSV first');\n  return fetch(`/console/api/datasets/${ids.dataset}/documents/${ids.document}/segments/batch_import`, {\n    method: 'POST',\n    headers: {'Content-Type': 'application/json'},\n    body: JSON.stringify({upload_file_id: uploadFileId}),\n  });\n}","typeGuard":"function isValidUploadFileId(id) {\n  return typeof id === 'string' && /^[0-9a-fA-F-]{36}$/.test(id) && id !== '00000000-0000-0000-0000-000000000000';\n}","tryCatchPattern":"try {\n  await batchImport(uploadFileId, ids);\n} catch (e) {\n  if (e.status === 404 && /UploadFile not found/.test(e.message)) {\n    // re-upload then retry once with the new id\n    const fresh = await uploadCsv(file);\n    await batchImport(fresh.id, ids);\n  } else throw e;\n}","preventionTips":["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."],"tags":["datasets","upload","batch-import","not-found","rest-api"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}