infiniflow/ragflow · error · RuntimeError
Database error (File retrieval)!
Error message
Database error (File retrieval)!
What it means
RuntimeError from FileService.get_by_pf_id_name when a file row matched by (parent_id, name) but the follow-up get_by_id on its id returns not-found. It signals an inconsistent read — the row existed for the SELECT then vanished (or get_by_id's filter differs), so the method refuses to return a half-resolved file.
Source
Thrown at api/db/services/file_service.py:171
kbs_info_list = []
for kb in list(kbs.dicts()):
kbs_info_list.append({"kb_id": kb["id"], "kb_name": kb["name"], "document_id": kb["document_id"]})
return kbs_info_list
@classmethod
@DB.connection_context()
def get_by_pf_id_name(cls, id, name):
# Get file by parent folder ID and name
# Args:
# id: Parent folder ID
# name: File name
# Returns:
# File object or None if not found
file = cls.model.select().where((cls.model.parent_id == id) & (cls.model.name == name))
if file.count():
e, file = cls.get_by_id(file[0].id)
if not e:
raise RuntimeError("Database error (File retrieval)!")
return file
return None
@classmethod
@DB.connection_context()
def get_id_list_by_id(cls, id, name, count, res):
# Recursively get list of file IDs by traversing folder structure
# Args:
# id: Starting folder ID
# name: List of folder names to traverse
# count: Current depth in traversal
# res: List to store results
# Returns:
# List of file IDs
if count < len(name):
file = cls.get_by_pf_id_name(id, name[count])
if file:
res.append(file.id)View on GitHub (pinned to 554fb1133a)
Solutions
- Retry the operation once after re-querying — this is a transient race in most cases.
- Avoid deleting and reading the same folder path concurrently; serialize folder mutations per user.
- If persistent, inspect the matched row (id, flags) to see why get_by_id rejects it.
Example fix
# before: single attempt
f = FileService.get_by_pf_id_name(folder_id, name)
# after: tolerate the race
for _ in range(2):
try:
f = FileService.get_by_pf_id_name(folder_id, name); break
except RuntimeError:
continue Defensive patterns
Strategy: retry
Validate before calling
row = FileService.model.select().where(FileService.model.parent_id == id, FileService.model.name == name)
if not row.count():
return None # no conflict — nothing to defend against yet Try / catch
for attempt in range(2):
try:
return FileService.get_by_pf_id_name(id, name)
except RuntimeError as e:
if 'File retrieval' not in str(e) or attempt == 1:
raise
continue # row vanished mid-read; re-select Prevention
- Serialize folder mutations per folder (lock or single-writer queue) in multi-client apps.
- Treat this as a transient race first; escalate only when it repeats.
When it happens
Trigger: Folder listing/upload-name check racing a delete: select finds the row, deletion commits, get_by_id misses. Also possible when the matched row is filtered out by get_by_id's conditions.
Common situations: Concurrent uploads and deletes in the same folder (two clients); duplicated name check colliding with cleanup jobs; rare in single-user flows.
Related errors
- Database error (File doesn't exist)!
- Database error (File)!
- Database error (File move)!
- Database error (list_by_parent_id)!
- Failed to create skill folder
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/123acb15fdaa5c13.
Report an issue: GitHub.