HumanSignal/label-studio · error · ValidationError
exc.kwargs['report']
Error message
exc.kwargs['report']
What it means
S3StorageSerializerMixin.validate_bucket() runs boto3's validate_bucket_name on the submitted bucket. If the value fails boto3's client-side parameter validation, a botocore ParamValidationError carrying a human-readable `report` is converted into a DRF ValidationError with that report text. It fires before any network call.
Source
Thrown at label_studio/io_storages/s3/serializers.py:33
logger = logging.getLogger(__name__)
class S3StorageSerializerMixin:
secure_fields = ['aws_access_key_id', 'aws_secret_access_key']
def to_representation(self, instance):
result = super().to_representation(instance)
for attr in self.secure_fields:
result.pop(attr)
return result
def validate_bucket(self, value):
if not value:
return value
try:
validate_bucket_name({'Bucket': value})
except ParamValidationError as exc:
raise ValidationError(exc.kwargs['report']) from exc
return value
def validate(self, data):
data = super().validate(data)
if not data.get('bucket', None):
return data
storage = self.instance
if storage:
for key, value in data.items():
setattr(storage, key, value)
else:
if 'id' in self.initial_data:
storage_object = self.Meta.model.objects.get(id=self.initial_data['id'])
for attr in self.secure_fields:
data[attr] = data.get(attr) or getattr(storage_object, attr)
storage = self.Meta.model(**data)
try:View on GitHub (pinned to 0b49e9b539)
Solutions
- Send only the bare bucket name (3–63 chars, lowercase letters, numbers, dots/hyphens) in the `bucket` field.
- Strip any s3:// scheme or path from the value before submitting.
- Pre-validate the name with botocore's validate_bucket_name in your client code.
Example fix
// before
{"bucket": "s3://My_Bucket/data"}
// after
{"bucket": "my-bucket"} Defensive patterns
Strategy: validation
Validate before calling
import re
BUCKET_RE = re.compile(r'^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$')
def valid_bucket_name(name: str) -> bool:
return bool(name) and bool(BUCKET_RE.match(name)) and '..' not in name
if not valid_bucket_name(payload['bucket']):
raise ValueError('bucket must be 3-63 chars, lowercase letters/numbers/dots/hyphens') Type guard
def is_bare_bucket_name(value: str) -> bool:
return isinstance(value, str) and not value.startswith('s3://') and '/' not in value Try / catch
try:
serializer.is_valid(raise_exception=True)
except ValidationError as e:
# e.detail carries the botocore report; fix the bucket field accordingly
logger.warning('Bucket name rejected: %s', e.detail) Prevention
- Send only the bare bucket name — never a full s3:// URL or path.
- Validate names with botocore's validate_bucket_name in client-side forms.
- Watch for env-substitution placeholders like ${BUCKET} leaking into payloads.
- Strip whitespace before submitting.
When it happens
Trigger: Submitting an S3 storage create/update request whose `bucket` field violates S3 naming rules (empty after strip, uppercase, invalid characters, too long, leading/trailing dots/dashes).
Common situations: Pasting a full s3://bucket/path URL into the bucket field; bucket names with underscores or uppercase from older setups; accidental whitespace; env-substitution leaving a placeholder like ${BUCKET}.
Related errors
- Wrong credentials for S3 {bucket_name}
- Cannot find bucket {bucket_name} in S3
- It seems access keys are incorrect
- {storage.url_scheme}://{storage.bucket}/{storage.prefix} not
- {underlying connection validation error}
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/d80fb08d3e83ba98.
Report an issue: GitHub.