infiniflow/ragflow · error · RuntimeError
Database error (File move)!
Error message
Database error (File move)!
What it means
Raised by FileService.move_file when cls.filter_update on the file rows fails. The update sets parent_id = folder_id for all ids in file_ids; any DB exception during that UPDATE (constraint, lock, invalid folder_id) is logged and re-raised as this RuntimeError.
Source
Thrown at api/db/services/file_service.py:538
"tenant_id": tenant_id,
"created_by": tenant_id,
"name": doc["name"],
"type": doc["type"],
"size": doc["size"],
"location": doc["location"],
"source_type": FileSource.KNOWLEDGEBASE,
}
cls.save(**file)
File2DocumentService.save(id=get_uuid(), file_id=file["id"], document_id=doc["id"])
@classmethod
@DB.connection_context()
def move_file(cls, file_ids, folder_id):
try:
cls.filter_update((cls.model.id << file_ids,), {"parent_id": folder_id})
except Exception:
logger.exception("move_file")
raise RuntimeError("Database error (File move)!")
@classmethod
@DB.connection_context()
def upload_document(self, kb, file_objs, user_id, src="local", parent_path: str | None = None, parser_config_override: dict | None = None):
root_folder = self.get_root_folder(user_id)
pf_id = root_folder["id"]
self.init_knowledgebase_docs(pf_id, user_id)
kb_root_folder = self.get_kb_folder(user_id)
kb_folder = self.new_a_file_from_kb(kb.tenant_id, kb.name, kb_root_folder["id"])
safe_parent_path = sanitize_path(parent_path)
# Merge parser_config_override with KB parser_config if provided
base_parser_config = kb.parser_config or {}
if parser_config_override and isinstance(parser_config_override, dict):
merged_parser_config = {**base_parser_config, **parser_config_override}
else:
merged_parser_config = base_parser_configView on GitHub (pinned to 554fb1133a)
Solutions
- Confirm the target folder exists and belongs to the same tenant before calling move_file.
- Check logs for the underlying Peewee error (usually IntegrityError or OperationalError).
- Retry the move after the concurrent operation finishes if the log shows a lock wait timeout.
- Reduce the batch size of file_ids if the update times out on large lists.
Example fix
# before
FileService.move_file(file_ids, folder_id)
# after
ok, target = FileService.get_by_id(folder_id)
if not ok or target.type != FileType.FOLDER.value:
return json_error_response('target folder not found', code=404)
FileService.move_file(file_ids, folder_id) Defensive patterns
Strategy: validation
Validate before calling
ok, target = FileService.get_by_id(folder_id)
if not ok:
return json_error_response('target folder not found', 404)
FileService.move_file(file_ids, folder_id) Type guard
def is_valid_move_target(folder_id: str, user_id: str) -> bool:
q = FileService.model.select().where(
(FileService.model.id == folder_id)
& (FileService.model.tenant_id == user_id)
& (FileService.model.type == FileType.FOLDER.value)
)
return q.exists() Try / catch
try:
FileService.move_file(file_ids, folder_id)
except RuntimeError as e:
return json_error_response(f'move failed: {e}', 500) Prevention
- Validate the destination folder in the same tenant before calling move APIs.
- Refresh folder trees in the UI when a 404/invalid-target response arrives.
- Batch large move requests to reduce lock contention.
When it happens
Trigger: Calling the file-move API with a target folder_id that does not exist or belongs to another tenant (FK violation), moving a very large id list that times out, or moving files while another transaction holds locks on those rows.
Common situations: Drag-and-drop in the web UI targeting a folder deleted in another session; API callers passing arbitrary folder ids without validation; concurrent moves/uploads on the same files.
Related errors
- Database error (list_by_parent_id)!
- Database error (File retrieval)!
- Database error (File doesn't exist)!
- Database error (File)!
- Database error (Document removal)!
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/d8c1015f61a6dff7.
Report an issue: GitHub.