HumanSignal/label-studio · error · DRFValidationError
extract_message(exc)
Error message
extract_message(exc)
What it means
For exceptions that are not Django/DRF ValidationErrors (e.g. ValueError from missing path, or unexpected errors from validate_connection), the Local Files import serializer converts them with extract_message and re-raises DRF ValidationError. This guarantees the API always returns a clean 400 message string instead of leaking a 500 stack trace. The message is the extracted str of the original exception.
Source
Thrown at label_studio/io_storages/localfiles/serializers.py:44
type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))
class Meta:
model = LocalFilesImportStorage
fields = '__all__'
def validate(self, data):
# Validate local file path
data = super(LocalFilesImportStorageSerializer, self).validate(data)
if 'path' in data:
data['path'] = normalize_storage_path(data['path'])
storage = LocalFilesImportStorage(**data)
try:
storage.validate_connection()
except (DjangoValidationError, DRFValidationError) as exc:
detail = getattr(exc, 'detail', getattr(exc, 'messages', str(exc)))
raise DRFValidationError(_stringify_detail(detail))
except Exception as exc:
raise DRFValidationError(extract_message(exc))
return data
class LocalFilesExportStorageSerializer(ExportStorageSerializer):
type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))
class Meta:
model = LocalFilesExportStorage
fields = '__all__'
def validate(self, data):
# Validate local file path
data = super(LocalFilesExportStorageSerializer, self).validate(data)
if 'path' in data:
data['path'] = normalize_storage_path(data['path'])
storage = LocalFilesExportStorage(**data)
try:
storage.validate_connection()View on GitHub (pinned to 0b49e9b539)
Solutions
- Include a non-empty 'path' field in the request payload (normalize_storage_path strips slashes; an empty/whitespace path triggers this)
- Read the returned 400 message — it is the original exception's message and points to the actual problem
- Fix whatever underlying condition extract_message reports (set the path, check the server environment/settings)
Example fix
// before
POST /api/storages/localfiles/ {"project": 1} // no path -> 400 'Path must be set for Local Files storage'
// after
POST /api/storages/localfiles/ {"project": 1, "path": "/label-studio/data/dataset1"} Defensive patterns
Strategy: try-catch
Validate before calling
payload = {"project": 1, "path": "/label-studio/data/dataset1"}
assert payload.get('path', '').strip(), "'path' is required for localfiles storage" Try / catch
try:
resp = requests.post(f'{host}/api/storages/localfiles/', json=payload)
resp.raise_for_status()
except requests.HTTPError:
print('Validation message:', resp.json().get('detail')) Prevention
- Always include a non-empty 'path' in localfiles storage payloads
- Treat the 400 message as the underlying exception text and fix that condition
- Test storage creation against a staging instance with the same env settings
When it happens
Trigger: POST/PATCH /api/storages/localfiles/ where storage.validate_connection raises a non-ValidationError: path missing entirely ('Path must be set for Local Files storage' ValueError) or any unexpected exception during connection validation.
Common situations: Omitting the 'path' field in the storage payload; client bugs sending null path; environment problems (unreadable settings) surfacing as generic extracted messages in a 400.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- _stringify_detail(detail)
- transition_name: Unknown transition for this entity
- Can't deserialize tasks due to {errors}
- Incorrect value type in key "{key}" = "{value}". It should b
- Incorrect value type in key "{key}" = "{value}". It should b
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/6404c039c5986a98.
Report an issue: GitHub.