{"record":{"id":"8dffe11be2a4023c","repo":"infiniflow/ragflow","slug":"database-error-file","errorCode":null,"errorMessage":"Database error (File)!","messagePattern":"Database error \\(File\\)!","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"critical","filePath":"api/db/services/file2document_service.py","lineNumber":51,"sourceCode":"        return list(objs)\n\n    @classmethod\n    @DB.connection_context()\n    def get_by_document_id(cls, document_id):\n        objs = cls.model.select().where(cls.model.document_id == document_id)\n        return list(objs)\n\n    @classmethod\n    @DB.connection_context()\n    def get_by_document_ids(cls, document_ids):\n        objs = cls.model.select().where(cls.model.document_id.in_(document_ids))\n        return list(objs.dicts())\n\n    @classmethod\n    @DB.connection_context()\n    def insert(cls, obj):\n        if not cls.save(**obj):\n            raise RuntimeError(\"Database error (File)!\")\n        return File2Document(**obj)\n\n    @classmethod\n    @DB.connection_context()\n    def delete_by_file_id(cls, file_id):\n        return cls.model.delete().where(cls.model.file_id == file_id).execute()\n\n    @classmethod\n    @DB.connection_context()\n    def delete_by_document_ids_or_file_ids(cls, document_ids, file_ids):\n        if not document_ids:\n            return cls.model.delete().where(cls.model.file_id.in_(file_ids)).execute()\n        elif not file_ids:\n            return cls.model.delete().where(cls.model.document_id.in_(document_ids)).execute()\n        return cls.model.delete().where(cls.model.document_id.in_(document_ids) | cls.model.file_id.in_(file_ids)).execute()\n\n    @classmethod\n    @DB.connection_context()","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/api/db/services/file2document_service.py#L33-L69","documentation":"RuntimeError from File2DocumentService.insert when saving the link row fails (cls.save returns falsy). Mirrors the Document insert guard: schema/constraint violations on the File2Document join table surface here and roll back the transaction.","triggerScenarios":"Creating a file-document association with invalid field values — nonexistent file_id or document_id, duplicate pair, or fields not on the model.","commonSituations":"Linking a document to a file after the file row was deleted; retrying an insert for a pair already linked; passing extra keys not in the model.","solutions":["Validate that both file_id and document_id exist before inserting the association.","Check for an existing link and update/skip instead of re-inserting.","Restrict the dict to File2Document model fields."],"exampleFix":"# before\nFile2DocumentService.insert({\"file_id\": f, \"document_id\": d})\n# after\nexists = File2DocumentService.get_by_file_id(f)\nif not any(x[\"document_id\"] == d for x in exists):\n    File2DocumentService.insert({\"id\": get_uuid(), \"file_id\": f, \"document_id\": d})","handlingStrategy":"validation","validationCode":"existing = File2DocumentService.get_by_document_ids([document_id])\nif any(str(x.get('file_id')) == str(file_id) for x in existing):\n    return  # link already present, skip insert\nFile2DocumentService.insert({\"id\": get_uuid(), \"file_id\": file_id, \"document_id\": document_id})","typeGuard":null,"tryCatchPattern":"try:\n    File2DocumentService.insert(obj)\nexcept RuntimeError as e:\n    if 'Database error (File)' in str(e):\n        # verify both endpoints exist, fix obj fields, then retry once\n        verify_file_and_document(obj)","preventionTips":["Make link creation check-then-insert (idempotent by file_id+document_id).","Confirm file and document rows exist in the same tenant before linking."],"tags":["database","insert","file2document","persistence"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}