{"record":{"id":"9b8ca2560026e042","repo":"infiniflow/ragflow","slug":"tenant-not-found-9b8ca2","errorCode":null,"errorMessage":"Tenant not found!","messagePattern":"Tenant not found!","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"api/db/services/file_service.py","lineNumber":718,"sourceCode":"        bname = f\"{user_id}-downloads\"\n        return settings.STORAGE_IMPL.put(bname, location, blob)\n\n    @classmethod\n    @DB.connection_context()\n    def delete_docs(cls, doc_ids, tenant_id):\n        root_folder = FileService.get_root_folder(tenant_id)\n        pf_id = root_folder[\"id\"]\n        FileService.init_knowledgebase_docs(pf_id, tenant_id)\n        errors = \"\"\n        kb_table_num_map = {}\n        for doc_id in doc_ids:\n            try:\n                e, doc = DocumentService.get_by_id(doc_id)\n                if not e:\n                    raise RuntimeError(\"document not found\")\n                tenant_id = DocumentService.get_tenant_id(doc_id)\n                if not tenant_id:\n                    raise RuntimeError(\"Tenant not found!\")\n\n                b, n = File2DocumentService.get_storage_address(doc_id=doc_id)\n\n                TaskService.filter_delete([Task.doc_id == doc_id])\n                if not DocumentService.remove_document(doc, tenant_id):\n                    raise RuntimeError(\"Database error (Document removal)!\")\n\n                f2d = File2DocumentService.get_by_document_id(doc_id)\n                deleted_file_count = 0\n                if f2d:\n                    deleted_file_count = FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])\n                File2DocumentService.delete_by_document_id(doc_id)\n                if deleted_file_count > 0:\n                    settings.STORAGE_IMPL.rm(b, n)\n\n                doc_parser = doc.parser_id\n                if doc_parser == ParserType.TABLE:\n                    kb_id = doc.kb_id","sourceCodeStart":700,"sourceCodeEnd":736,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/file_service.py#L700-L736","documentation":"Raised in FileService.delete_docs when DocumentService.get_tenant_id(doc_id) returns falsy for a document that was just fetched. It means the document row exists but its tenant cannot be resolved (join to tenant/kb failed), so ownership cannot be verified before deletion proceeds.","triggerScenarios":"A document row whose kb_id/tenant_id references a deleted knowledge base or tenant; data restored partially; concurrent deletion of the parent KB between get_by_id and get_tenant_id.","commonSituations":"Orphaned documents left by older bugs or manual DB surgery; deleting documents right as their dataset is being removed in another session.","solutions":["Inspect the document row's kb_id and trace it to the knowledge base and tenant tables; repair or remove the orphaned row.","If the parent dataset was deleted concurrently, refresh the document list and skip this id.","Run the deletion again after fixing referential integrity.","Avoid manual deletes that bypass DocumentService, which can create such orphans."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"tenant_id = DocumentService.get_tenant_id(doc_id)\nif not tenant_id:\n    skip_or_quarantine(doc_id)  # orphaned document, do not hard-delete blindly","typeGuard":null,"tryCatchPattern":"try:\n    FileService.delete_docs([doc_id], tenant_id)\nexcept RuntimeError as e:\n    if 'Tenant not found' in str(e):\n        quarantine_orphaned_document(doc_id)\n    raise","preventionTips":["Never delete knowledge bases or tenants with raw SQL; use the service APIs so documents stay consistent.","Periodically check for documents whose kb_id has no matching knowledgebase row.","Avoid racing dataset deletion with document deletion in automation."],"tags":["data-integrity","tenant","delete","orphaned-record"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}