HumanSignal/label-studio · error · ValueError

Failed to read file {path}: {str(e)}

Error message

Failed to read file {path}: {str(e)}

What it means

When Local Files import storage reads a task file that is not in use_blob_urls mode, it opens the file and parses it with load_tasks_json. If the open/read raises OSError (permission denied, file deleted between scan and read, I/O error), get_data wraps it in a ValueError carrying the OS message. This surfaces during storage sync when converting scanned files into tasks.

Source

Thrown at label_studio/io_storages/localfiles/models.py:168

    def get_data(self, key) -> list[StorageObject]:
        path = Path(key)
        if self.use_blob_urls:
            # include self-hosted links pointed to local resources via
            # {settings.HOSTNAME}/data/local-files?d=<path/to/local/dir>
            document_root = Path(settings.LOCAL_FILES_DOCUMENT_ROOT)
            relative_path = str(path.relative_to(document_root))
            task = {
                settings.DATA_UNDEFINED_NAME: f'{settings.HOSTNAME}/data/local-files/?d={quote(str(relative_path))}'
            }
            return [StorageObject(key=key, task_data=task)]

        try:
            with open(path, 'rb') as f:
                blob = f.read()
                return load_tasks_json(blob, key)
        except OSError as e:
            raise ValueError(f'Failed to read file {path}: {str(e)}')

    def scan_and_create_links(self):
        return self._scan_and_create_links(LocalFilesImportStorageLink)

    class Meta:
        abstract = True


class LocalFilesImportStorage(ProjectStorageMixin, LocalFilesImportStorageBase):
    class Meta:
        abstract = False


class LocalFilesExportStorage(LocalFilesMixin, ExportStorage):
    def save_annotation(self, annotation):
        logger.debug(f'Creating new object on {self.__class__.__name__} Storage {self} for annotation {annotation}')
        ser_annotation = self._get_serialized_data(annotation)

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Fix file permissions so the Label Studio process user can read them (chmod/chown, or match UID in the container)
  2. Re-scan/re-sync so deleted files are removed from the pending list, and remove stale/broken symlinks from the directory
  3. Check the OS message embedded in the error (e.g. 'Permission denied' vs 'No such file or directory') to pick between permission and missing-file fixes
  4. If the files are raw images/blobs rather than task JSON, enable use_blob_urls so they are referenced as URLs instead of parsed

Example fix

// before
# host file: -rw------- root root task.json, Label Studio runs as appuser -> OSError
// after
sudo chown -R 10001:10001 /label-studio/data/dataset1   # or chmod o+r the task files
Defensive patterns

Strategy: try-catch

Validate before calling

import os
path = '/label-studio/data/dataset1/task.json'
if not os.path.isfile(path) or not os.access(path, os.R_OK):
    raise SystemExit(f'File missing or unreadable by Label Studio user: {path}')

Type guard

def is_readable_file(path: str) -> bool:
    from pathlib import Path
    p = Path(path)
    return p.is_file() and os.access(p, os.R_OK)

Try / catch

try:
    tasks = storage.get_data(key)
except ValueError as e:
    logger.error('Local file read failed during sync: %s — check permissions/staleness', e)

Prevention

When it happens

Trigger: Syncing a Local Files import storage where a scanned file cannot be opened: file permissions unreadable by the Label Studio process user, the file was removed after the directory scan, a broken symlink, or a disk/device error during read.

Common situations: Files owned by root while Label Studio runs as another user in Docker; NFS/bind-mount permission mismatches; race between dataset regeneration and a sync; files with restrictive modes like 0600.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/e21db6f36a8d505a. Report an issue: GitHub.