infiniflow/ragflow · error · RuntimeError
DATA_ERROR
DATA_ERROR
Error message
The folder is already in the target location. There is no need to move it.
What it means
Raised inside the recursive folder-move helper in file_api_service when the source folder entry's id equals the destination folder entry's id — i.e. the code is asked to move a folder into itself. This is a defensive guard: the earlier pre-checks (move-to-itself and move-into-own-subfolder) should normally catch this, so hitting it means an entry was reached during recursion whose destination is itself, indicating inconsistent parent/child state or a stale destination.
Source
Thrown at api/apps/services/file_api_service.py:513
for f in FileService.query(name=new_name, parent_id=target_parent_id):
if f.name == new_name:
return False, "Duplicated file name in the same folder."
if dest_folder:
for file in files:
if file.type == FileType.FOLDER.value and file.id == dest_folder.id:
return False, "Cannot move a folder to itself."
# Check if any source folder is an ancestor of the destination folder
# to prevent infinite recursion in _move_entry_recursive
dest_ancestors = FileService.get_all_parent_folders(dest_folder.id)
dest_ancestor_ids = {f.id for f in dest_ancestors}
for file in files:
if file.type == FileType.FOLDER.value and file.id in dest_ancestor_ids:
return False, "Cannot move a folder into its own subfolder."
def _move_entry_recursive(source_file_entry, dest_folder_entry, override_name=None):
if source_file_entry.id == dest_folder_entry.id:
raise RuntimeError("The folder is already in the target location. There is no need to move it.")
effective_name = override_name or source_file_entry.name
if source_file_entry.type == FileType.FOLDER.value:
existing_folder = FileService.query(name=effective_name, parent_id=dest_folder_entry.id)
if existing_folder:
if existing_folder[0].id == source_file_entry.id:
raise RuntimeError("The folder is already in the target location. There is no need to move it.")
new_folder = existing_folder[0]
else:
new_folder = FileService.insert(
{
"id": get_uuid(),
"parent_id": dest_folder_entry.id,
"tenant_id": source_file_entry.tenant_id,
"created_by": source_file_entry.tenant_id,
"name": effective_name,
"location": "",
"size": 0,View on GitHub (pinned to 554fb1133a)
Solutions
- Filter the destination folder id (and its descendants) out of the source file list before calling the move API
- Run the move with only file ids plus folders that are genuinely outside the destination subtree
- If it persists, audit folder parent_id chains for cycles (SELECT id, parent_id and walk ancestors)
- Refresh the file tree in the UI and re-select — a stale tree often contains the destination in the selection
Example fix
# before move(src_file_ids=[dest_id, *child_ids], dest_id=dest_id) # after src_ids = [fid for fid in child_ids if fid != dest_id] move(src_file_ids=src_ids, dest_id=dest_id)
Defensive patterns
Strategy: validation
Validate before calling
# before move: dest must not appear in sources or their ancestor chain src_ids = [f for f in src_ids if f != dest_id] # if ancestor map is available client-side, also drop descendants of dest
Try / catch
try:
move(src_ids, dest_id)
except RuntimeError as e:
if "already in the target location" in str(e):
pass # no-op: treat as success after verifying parent_id == dest_id
else:
raise Prevention
- Exclude the destination folder from the multi-select before dragging
- Compare each source's parent_id with dest_id client-side and skip equals
- Refresh the folder tree before bulk moves to avoid stale selections
When it happens
Trigger: POST move/rename where source_files includes the destination folder id itself (pre-check bypassed via mixed file/folder payloads), or where DB folder rows have cyclic parent_id references so the recursion re-enters the same folder. Also reachable when an existing same-name folder lookup returns the source itself.
Common situations: Frontends that send the whole current folder selection including the target; concurrent moves that create parent cycles; DB rows manually edited so parent_id points at a descendant; retries of a move that already completed.
Related errors
- Param define nesting too deep!!!, can not parse it
- Database error (File move)!
- At least one of dest_file_id or new_name must be provided
- new_name can only be used with a single file
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/c7ef6c5ce546371b.
Report an issue: GitHub.