{"record":{"id":"50073a69746b1ded","repo":"unslothai/unsloth","slug":"s3-config-bucket-is-required","errorCode":null,"errorMessage":"s3_config.bucket is required","messagePattern":"s3_config\\.bucket is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/training/s3_dataset.py","lineNumber":166,"sourceCode":"def prepare_s3_dataset_download(\n    s3_config: dict,\n    dest_dir: Optional[str] = None,\n    cancel_callback: Optional[Callable[[], bool]] = None,\n) -> S3DatasetDownload:\n    \"\"\"Download supported dataset files from S3 to a local directory.\n\n    Returns the local files plus the owned temporary directory, when one was\n    created. Call ``cleanup()`` after the dataset loader has materialized data.\n\n    Raises ``RuntimeError`` if boto3 is missing, and ``ValueError`` if the\n    bucket/prefix contains no supported dataset files.\n    \"\"\"\n    if not boto3_available():\n        raise RuntimeError(\"S3 dataset loading requires boto3. Install it with: pip install boto3\")\n\n    bucket = s3_config.get(\"bucket\")\n    if not bucket:\n        raise ValueError(\"s3_config.bucket is required\")\n    prefix = s3_config.get(\"prefix\")\n\n    _raise_if_cancelled(cancel_callback)\n    client = _build_s3_client(s3_config)\n\n    keys = _list_dataset_keys(client, bucket, prefix)\n    _raise_if_cancelled(cancel_callback)\n    if not keys:\n        where = f\"s3://{bucket}/{prefix}\" if prefix else f\"s3://{bucket}\"\n        raise ValueError(\n            f\"No supported dataset files ({', '.join(SUPPORTED_EXTENSIONS)}) \"\n            f\"found under {where}\"\n        )\n\n    _validate_single_extension_family(keys)\n\n    owns_temp_dir = dest_dir is None\n    target_dir = dest_dir or tempfile.mkdtemp(prefix = \"unsloth_s3_dataset_\")","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/s3_dataset.py#L148-L184","documentation":"ValueError raised by prepare_s3_dataset_download when s3_config.get(\"bucket\") is falsy. The bucket name is the one mandatory field of the s3_config dict — before any client is built or any S3 call is made, the function validates its presence so a missing bucket produces a clear message rather than a cryptic ParamValidationError from boto3.","triggerScenarios":"Calling prepare_s3_dataset_download({}) or {\"prefix\": \"data/\"} — any dict where 'bucket' is absent, None, or an empty string.","commonSituations":"UI form submitted with the bucket field left blank; config file/YAML with a typo'd or omitted bucket key; programmatic construction where the bucket variable is conditionally defined and ends up None.","solutions":["Set s3_config['bucket'] to the target S3 bucket name.","Validate the form/config upstream so the user is prompted for the bucket before the call.","Check for typos like 'Bucket' vs 'bucket' — the key is case-sensitive."],"exampleFix":"// before\nprepare_s3_dataset_download({\"prefix\": \"datasets/x/\"})\n// after\nprepare_s3_dataset_download({\"bucket\": \"my-datasets\", \"prefix\": \"datasets/x/\"})","handlingStrategy":"validation","validationCode":"assert isinstance(s3_config, dict) and s3_config.get('bucket'), \\\n    \"s3_config must include a non-empty 'bucket' key\"","typeGuard":"def is_valid_s3_config(cfg: object) -> bool:\n    return isinstance(cfg, dict) and isinstance(cfg.get('bucket'), str) and bool(cfg['bucket'].strip())","tryCatchPattern":"try:\n    dl = prepare_s3_dataset_download(cfg)\nexcept ValueError as e:\n    if 'bucket is required' in str(e):\n        cfg['bucket'] = prompt_user_for_bucket()  # re-prompt and retry","preventionTips":["Validate the config dict shape at the API/form boundary before it reaches training code.","Reject empty bucket fields in the UI, not in the backend download path.","Keep the key lowercase 'bucket' — the lookup is exact."],"tags":["s3","config","validation","dataset"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}