{"record":{"id":"6404c039c5986a98","repo":"HumanSignal/label-studio","slug":"extract-message-exc-6404c0","errorCode":null,"errorMessage":"extract_message(exc)","messagePattern":"extract_message\\(exc\\)","errorType":"validation","errorClass":"DRFValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/io_storages/localfiles/serializers.py","lineNumber":44,"sourceCode":"    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))\n\n    class Meta:\n        model = LocalFilesImportStorage\n        fields = '__all__'\n\n    def validate(self, data):\n        # Validate local file path\n        data = super(LocalFilesImportStorageSerializer, self).validate(data)\n        if 'path' in data:\n            data['path'] = normalize_storage_path(data['path'])\n        storage = LocalFilesImportStorage(**data)\n        try:\n            storage.validate_connection()\n        except (DjangoValidationError, DRFValidationError) as exc:\n            detail = getattr(exc, 'detail', getattr(exc, 'messages', str(exc)))\n            raise DRFValidationError(_stringify_detail(detail))\n        except Exception as exc:\n            raise DRFValidationError(extract_message(exc))\n        return data\n\n\nclass LocalFilesExportStorageSerializer(ExportStorageSerializer):\n    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))\n\n    class Meta:\n        model = LocalFilesExportStorage\n        fields = '__all__'\n\n    def validate(self, data):\n        # Validate local file path\n        data = super(LocalFilesExportStorageSerializer, self).validate(data)\n        if 'path' in data:\n            data['path'] = normalize_storage_path(data['path'])\n        storage = LocalFilesExportStorage(**data)\n        try:\n            storage.validate_connection()","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/io_storages/localfiles/serializers.py#L26-L62","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nPOST /api/storages/localfiles/ {\"project\": 1}   // no path -> 400 'Path must be set for Local Files storage'\n// after\nPOST /api/storages/localfiles/ {\"project\": 1, \"path\": \"/label-studio/data/dataset1\"}","handlingStrategy":"try-catch","validationCode":"payload = {\"project\": 1, \"path\": \"/label-studio/data/dataset1\"}\nassert payload.get('path', '').strip(), \"'path' is required for localfiles storage\"","typeGuard":null,"tryCatchPattern":"try:\n    resp = requests.post(f'{host}/api/storages/localfiles/', json=payload)\n    resp.raise_for_status()\nexcept requests.HTTPError:\n    print('Validation message:', resp.json().get('detail'))","preventionTips":["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"],"tags":["api","serialization","validation","django"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}