HumanSignal/label-studio · error · ValueError
Task is required to resolve URIs in data={data}
Error message
Task is required to resolve URIs in data={data} What it means
resolve_uris replaces all storage-scheme URIs found in a task data string with proxy URLs; that substitution requires the owning Task. It raises this ValueError when at least one resolvable URI was found (get_all_uris_via_regex matched) but the task argument is None, since each URI needs task.id for the proxy route.
Source
Thrown at label_studio/io_storages/base_models.py:460
if isinstance(data, list):
resolved = [self.resolve_uris(item, task) or item for item in data]
return resolved
if isinstance(data, dict):
resolved = {key: self.resolve_uris(val, task) or val for key, val in data.items()}
return resolved
if not isinstance(data, str) or self.url_scheme not in data:
return None
try:
all_uris = get_all_uris_via_regex(data, prefixes=[self.url_scheme])
if not all_uris:
return None
if task is None:
logger.error(f'Task is required to resolve URIs in data={data}', exc_info=True)
raise ValueError(f'Task is required to resolve URIs in data={data}')
resolved = data
any_resolved = False
for extracted_uri, _ in all_uris:
if not self.can_resolve_url(extracted_uri):
continue
proxy_url = urljoin(
settings.HOSTNAME,
reverse('storages:task-storage-data-resolve', kwargs={'task_id': task.id})
+ f'?fileuri={base64.urlsafe_b64encode(extracted_uri.encode()).decode()}',
)
resolved = resolved.replace(extracted_uri, proxy_url, 1)
any_resolved = True
return resolved if any_resolved else None
except Exception:
logger.info(f"Can't resolve URIs in data={data}", exc_info=True)
return None
View on GitHub (pinned to 0b49e9b539)
Solutions
- Provide the Task instance owning the data when calling resolve_uris.
- Skip resolution when no task is available — check can_resolve_url / regex yourself first and only call with a task.
- Fetch or pass the task id through your pipeline so resolution happens in task context.
Example fix
// before resolved = storage.resolve_uris(task_data_json, task=None) // after resolved = storage.resolve_uris(task_data_json, task=task) # task from the annotation/loop context
Defensive patterns
Strategy: validation
Validate before calling
from label_studio.io_storages.functions import get_all_uris_via_regex
all_uris = get_all_uris_via_regex(data, prefixes=[storage.url_scheme])
if all_uris and task is None:
raise ValueError('Resolving these URIs requires the owning Task') Type guard
def resolution_possible(data, task, storage) -> bool:
has_uris = bool(get_all_uris_via_regex(data, prefixes=[storage.url_scheme]))
return not has_uris or task is not None Try / catch
try:
resolved = storage.resolve_uris(data, task=task)
except ValueError as e:
if 'Task is required' in str(e):
resolved = data # leave URIs unresolved when no task context
else:
raise Prevention
- Carry the Task reference alongside data strings in export/import pipelines.
- Pre-scan data for scheme URIs to decide whether task context is needed before calling resolve_uris.
- Never call resolve_uris with task=None on data you know contains storage URIs.
When it happens
Trigger: Calling resolve_uris(data, task=None) where data contains at least one URI matching the storage url_scheme prefix and passing can_resolve_url.
Common situations: Bulk URI resolution utilities invoked without task context; export/import flows that pass data strings around without carrying the Task reference.
Related errors
- Task is required to resolve URI={uri}
- 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/e7b483db962359b2.
Report an issue: GitHub.