infiniflow/ragflow · error · RuntimeError

Database error (File)!

Error message

Database error (File)!

What it means

Raised by FileService.insert when cls.save(**file) returns falsy, meaning Peewee failed to persist the new File record (or save returned 0 rows affected). The RuntimeError signals the INSERT did not succeed, typically a constraint violation or invalid field data surfaced through save().

Source

Thrown at api/db/services/file_service.py:466

            e, file = cls.get_by_id(current_id)
            if e and file.parent_id != file.id:
                parent_folders.append(file)
                current_id = file.parent_id
            else:
                parent_folders.append(file)
                break
        return parent_folders

    @classmethod
    @DB.connection_context()
    def insert(cls, file):
        # Insert a new file record
        # Args:
        #     file: File data dictionary
        # Returns:
        #     Created file object
        if not cls.save(**file):
            raise RuntimeError("Database error (File)!")
        return File(**file)

    @classmethod
    @DB.connection_context()
    def delete(cls, file):
        return cls.delete_by_id(file.id)

    @classmethod
    @DB.connection_context()
    def delete_by_pf_id(cls, folder_id):
        return cls.model.delete().where(cls.model.parent_id == folder_id).execute()

    @classmethod
    @DB.connection_context()
    def delete_folder_by_pf_id(cls, user_id, folder_id):
        try:
            files = cls.model.select().where((cls.model.tenant_id == user_id) & (cls.model.parent_id == folder_id))
            for file in files:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Inspect the server log for the underlying Peewee/MySQL error logged just before this raise; fix the identified column/constraint.
  2. Ensure file['id'] is a fresh uuid (get_uuid()) and not an existing primary key.
  3. Verify parent_id references an existing file row and tenant_id references an existing tenant.
  4. After upgrading RAGFlow, re-run migrations so the file table schema matches the model.

Example fix

# before
file['id'] = client_provided_id  # may collide
FileService.insert(file)

# after
file['id'] = get_uuid()
FileService.insert(file)
Defensive patterns

Strategy: try-catch

Validate before calling

required = {'id', 'parent_id', 'tenant_id', 'name', 'type'}
missing = required - set(file.keys())
assert not missing, f'missing fields: {missing}'
ok, parent = FileService.get_by_id(file['parent_id'])
assert ok, 'parent folder must exist'

Type guard

def is_insertable_file_dict(file: dict) -> bool:
    return (
        isinstance(file, dict)
        and isinstance(file.get('id'), str)
        and not FileService.model.select().where(FileService.model.id == file['id']).exists()
        and FileService.model.select().where(FileService.model.id == file.get('parent_id')).exists()
    )

Try / catch

try:
    FileService.insert(file)
except RuntimeError:
    logger.exception('file insert failed')
    raise ValidationError('could not create file record')

Prevention

When it happens

Trigger: Inserting a file dict with a duplicate primary key id, a parent_id that violates a foreign-key constraint, a tenant_id that does not exist, missing required columns, or a field value of the wrong type.

Common situations: Reusing a client-supplied uuid that already exists; uploading into a folder id that was deleted mid-request; schema drift after a RAGFlow upgrade adding NOT NULL columns; passing None for tenant_id.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/5b4e1fa39257da88. Report an issue: GitHub.