HumanSignal/label-studio · error · NotImplementedError
NotImplementedError
Error message
NotImplementedError
What it means
ImportStorage.iter_objects is the abstract hook a backend must implement to yield storage objects during a synchronization scan. The base class raises NotImplementedError, so calling it on a subclass without an override (or on the base class itself) always fails. It is invoked by ImportStorage.create / sync paths when linking tasks.
Source
Thrown at label_studio/io_storages/base_models.py:330
description = models.TextField(_('description'), null=True, blank=True, help_text='Cloud storage description')
created_at = models.DateTimeField(_('created at'), auto_now_add=True, help_text='Creation time')
synchronizable = models.BooleanField(_('synchronizable'), default=True, help_text='If storage can be synced')
def validate_connection(self, client=None):
raise NotImplementedError('validate_connection is not implemented')
class Meta:
abstract = True
class ImportStorage(Storage):
def iter_objects(self) -> Iterator[Any]:
"""
Returns:
Iterator[Any]: An iterator for objects in the storage.
"""
raise NotImplementedError
def iter_keys(self) -> Iterator[str]:
"""
Returns:
Iterator[str]: An iterator of keys for each object in the storage.
"""
raise NotImplementedError
def get_unified_metadata(self, obj: Any) -> dict:
"""
Args:
obj: The storage object to get metadata for
Returns:
dict: A dictionary of metadata for the object with keys:
'key', 'last_modified', 'size'.
"""
raise NotImplementedError
View on GitHub (pinned to 0b49e9b539)
Solutions
- Implement iter_objects in your ImportStorage subclass to yield objects (e.g. bucket object wrappers) from your backend.
- If your backend is key-listing only, implement both iter_keys and iter_objects so either scan path works.
- Verify the storage you synced is the concrete subclass (e.g. S3ImportStorage), not the abstract ImportStorage base.
Example fix
// before
class MyImportStorage(ImportStorage):
pass
// after
class MyImportStorage(ImportStorage):
def iter_objects(self):
for obj in self.client.list_objects():
yield obj Defensive patterns
Strategy: validation
Validate before calling
import inspect
if inspect.isabstract(type(storage)) or type(storage).iter_objects is ImportStorage.iter_objects:
raise TypeError(f'{type(storage).__name__} does not implement iter_objects') Type guard
def supports_object_iteration(storage) -> bool:
return type(storage).iter_objects is not ImportStorage.iter_objects Try / catch
try:
for obj in storage.iter_objects():
process(obj)
except NotImplementedError:
logger.error('%s cannot be synced: iter_objects not implemented', type(storage).__name__) Prevention
- Subclass a concrete backend (e.g. S3ImportStorage) rather than the abstract ImportStorage.
- Implement all abstract iteration hooks in custom backends and cover them with a smoke sync test in CI.
- Never instantiate or sync the abstract ImportStorage base directly.
When it happens
Trigger: Running a sync (_scan_and_create_links -> create -> iter_objects) on a custom ImportStorage subclass that does not implement iter_objects; instantiating ImportStorage directly and syncing.
Common situations: Custom storage integration missing the iter_objects method; refactoring moved the implementation into iter_keys only while the sync path still relies on iter_objects.
Related errors
- validate_connection is not implemented
- You do not have permission to create storages for this proje
- Failed to list storage files
- "form_layout.yml" is not found for {self.__class__.__name__}
- Azure account name and key must be set using environment var
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/9216d749342d3e53.
Report an issue: GitHub.