infiniflow/ragflow · error · ValueError
At least one of dest_file_id or new_name must be provided
Error message
At least one of dest_file_id or new_name must be provided
What it means
ValueError from MoveFileReq.check_operation, a model_validator(mode='after') on the file move/rename request model (api/utils/validation_utils.py:1091-1098). The move-files endpoint is a single endpoint for both moving and renaming; Pydantic rejects a payload that supplies neither a destination folder (dest_file_id) nor a new name (new_name), because the operation would be a no-op.
Source
Thrown at api/utils/validation_utils.py:1095
class DeleteFileReq(Base):
"""Request model for deleting files."""
ids: Annotated[list[str], Field(min_length=1)]
class MoveFileReq(Base):
"""Request model for moving or renaming files."""
src_file_ids: Annotated[list[str], Field(min_length=1)]
dest_file_id: Annotated[str | None, Field(default=None)]
new_name: Annotated[str | None, StringConstraints(strip_whitespace=True, min_length=1, max_length=255), Field(default=None)]
@model_validator(mode="after")
def check_operation(self):
"""Require either a destination folder or a new file name."""
if not self.dest_file_id and not self.new_name:
raise ValueError("At least one of dest_file_id or new_name must be provided")
if self.new_name and len(self.src_file_ids) > 1:
raise ValueError("new_name can only be used with a single file")
return self
class ListFileReq(BaseModel):
"""Request model for listing files."""
model_config = ConfigDict(extra="forbid")
parent_id: Annotated[str | None, Field(default=None)]
keywords: Annotated[str, Field(default="")]
page: Annotated[int, Field(default=1, ge=1)]
page_size: Annotated[int, Field(default=15, ge=1)]
orderby: Annotated[str, Field(default="create_time")]
desc: Annotated[bool, Field(default=True)]
@field_validator("page_size")View on GitHub (pinned to 554fb1133a)
Solutions
- Include dest_file_id (the target folder id) when moving files.
- Include new_name (1-255 chars after trimming) when renaming a single file.
- If moving to root, send the actual root folder id rather than an empty string.
- Trim user input before assigning it to new_name; all-whitespace names are treated as missing.
Example fix
// before
{"src_file_ids": ["f1"], "dest_file_id": "", "new_name": null}
// after
{"src_file_ids": ["f1"], "dest_file_id": "<root-or-folder-id>"} Defensive patterns
Strategy: validation
Validate before calling
if not payload.get("dest_file_id") and not payload.get("new_name", "").strip():
raise ValueError("move/rename requires dest_file_id or a non-empty new_name") Type guard
def is_valid_move_request(src: list[str], dest: str | None, new_name: str | None) -> bool:
return bool(src) and (bool(dest) or bool(new_name and new_name.strip())) Try / catch
try:
req = MoveFileReq(**payload)
except ValidationError as e:
if "At least one of dest_file_id or new_name" in str(e):
# surface to the UI: pick a destination or type a name
...
raise Prevention
- Trim new_name client-side; whitespace-only counts as missing.
- Disable the confirm button until destination or new name is chosen.
- Use the real root-folder id rather than empty string for root moves.
When it happens
Trigger: POST to the file move/rename API with only src_file_ids and both dest_file_id and new_name omitted, empty, or None. Also triggered when dest_file_id is an empty string (falsy check) or new_name is only whitespace (StringConstraints strip_whitespace + min_length=1 turns it into None/invalid).
Common situations: Front-end firing the move dialog with no target folder selected; sending an empty-string dest_file_id to mean 'root folder'; whitespace-only new_name from an untrimmed input field.
Related errors
- new_name can only be used with a single file
- invalid_uuid_format
- format_invalid
- duplicate_uuids
- main() must be defined or exported.
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/ba4c9c78f6cdc6e9.
Report an issue: GitHub.