{"record":{"id":"5d80e0754a3471f6","repo":"HumanSignal/label-studio","slug":"storage-url-scheme-storage-bucket-storage-p","errorCode":null,"errorMessage":"{storage.url_scheme}://{storage.bucket}/{storage.prefix} not found.","messagePattern":"(.+?)://(.+?)/(.+?) not found\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/io_storages/s3/serializers.py","lineNumber":74,"sourceCode":"            if (\n                e.response.get('Error').get('Code') in ['SignatureDoesNotMatch', '403']\n                or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 403\n            ):\n                raise ValidationError(\n                    'Cannot connect to S3 {bucket_name} with specified AWS credentials'.format(\n                        bucket_name=storage.bucket\n                    )\n                )\n            if (\n                e.response.get('Error').get('Code') in ['NoSuchBucket', '404']\n                or e.response.get('ResponseMetadata').get('HTTPStatusCode') == 404\n            ):\n                raise ValidationError('Cannot find bucket {bucket_name} in S3'.format(bucket_name=storage.bucket))\n        except TypeError as e:\n            logger.info(f'It seems access keys are incorrect: {e}', exc_info=True)\n            raise ValidationError('It seems access keys are incorrect')\n        except KeyError:\n            raise ValidationError(f'{storage.url_scheme}://{storage.bucket}/{storage.prefix} not found.')\n        return data\n\n\nclass S3ImportStorageSerializer(S3StorageSerializerMixin, ImportStorageSerializer):\n    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))\n    presign = serializers.BooleanField(required=False, default=True)\n\n    def validate_s3_endpoint(self, value):\n        if value and settings.SSRF_PROTECTION_ENABLED:\n            validate_url_for_ssrf(value, block_local_urls=True)\n        return value\n\n    class Meta:\n        model = S3ImportStorage\n        fields = '__all__'\n\n\nclass S3ExportStorageSerializer(S3StorageSerializerMixin, ExportStorageSerializer):","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/io_storages/s3/serializers.py#L56-L92","documentation":"The final except KeyError in S3StorageSerializerMixin.validate() surfaces the KeyError raised inside S3Storage.validate_connection() as ValidationError(f'{storage.url_scheme}://{storage.bucket}/{storage.prefix} not found.'). It reaches the API caller with the actual storage's scheme/bucket/prefix interpolated, meaning the bucket+prefix combination had no matching keys (see error 162).","triggerScenarios":"Any import-storage create/update where validate_connection()'s ListObjectsV2 returns KeyCount 0/None for the given bucket and prefix, triggering the KeyError that this handler converts.","commonSituations":"Same as prefix-not-found: empty bucket, wrong prefix, objects at root while a prefix is set, endpoint/region mismatch returning empty result sets.","solutions":["Upload at least one object under bucket/prefix before connecting the import storage.","Correct or remove the `prefix` field so it matches where files actually live.","Verify bucket/endpoint/region so listing hits the intended bucket."],"exampleFix":"// before\n{\"bucket\": \"my-bucket\", \"prefix\": \"imports/\"}   // bucket has files at root\n\n// after\n{\"bucket\": \"my-bucket\", \"prefix\": \"\"}","handlingStrategy":"validation","validationCode":"import boto3\n\ndef prefix_keycount(bucket: str, prefix: str, **client_kwargs) -> int:\n    s3 = boto3.client('s3', **client_kwargs)\n    return s3.list_objects_v2(Bucket=bucket, Prefix=prefix, MaxKeys=1).get('KeyCount', 0)\n\nif prefix_keycount('my-bucket', 'imports/') == 0:\n    raise ValueError('No objects under bucket/prefix; fix prefix or upload data first')","typeGuard":"def prefix_matches_layout(storage: dict) -> bool:\n    p = storage.get('prefix', '')\n    return p == '' or bool(storage.get('bucket'))","tryCatchPattern":"try:\n    serializer.is_valid(raise_exception=True)\nexcept ValidationError as e:\n    msg = str(e.detail)\n    if 'not found' in msg and '://' in msg:\n        # KeyError from validate_connection: bucket/prefix had zero keys\n        print(f'No objects at {msg}; adjust prefix or upload files')","preventionTips":["Dry-run ListObjectsV2 with the exact bucket/prefix before creating the storage.","Automate an upload-then-connect ordering in pipelines (data must exist first).","Standardize prefix conventions (trailing slash) across environments.","Use a health-check script that lists each configured storage prefix on deploy."],"tags":["s3","aws","not-found","prefix","serializer"],"backgroundTag":"s3-prefix-not-found","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}