{"record":{"id":"511e4c28fd7881a0","repo":"unslothai/unsloth","slug":"s3-dataset-download-cancelled","errorCode":null,"errorMessage":"S3 dataset download cancelled","messagePattern":"S3 dataset download cancelled","errorType":"exception","errorClass":"S3DownloadCancelled","httpStatus":null,"severity":"info","filePath":"studio/backend/core/training/s3_dataset.py","lineNumber":145,"sourceCode":"        f\"({', '.join(families)}). Keep one dataset format under the selected prefix.\"\n    )\n\n\ndef _unique_local_path(target_dir: str, filename: str, used_paths: set[str]) -> str:\n    \"\"\"Return an unused flattened path for an S3 object basename.\"\"\"\n    stem, ext = os.path.splitext(filename)\n    candidate = os.path.join(target_dir, filename)\n    suffix = 1\n    while candidate in used_paths or os.path.exists(candidate):\n        candidate = os.path.join(target_dir, f\"{stem}_{suffix}{ext}\")\n        suffix += 1\n    used_paths.add(candidate)\n    return candidate\n\n\ndef _raise_if_cancelled(cancel_callback: Optional[Callable[[], bool]]) -> None:\n    if cancel_callback is not None and cancel_callback():\n        raise S3DownloadCancelled(\"S3 dataset download cancelled\")\n\n\ndef 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","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/s3_dataset.py#L127-L163","documentation":"S3DownloadCancelled (a RuntimeError subclass, s3_dataset.py:39) raised by _raise_if_cancelled when the caller-supplied cancel_callback returns True. The download loop polls the callback at each phase (client build, listing, per-object download) so long S3 transfers can be aborted cooperatively. It is a control-flow signal, not a failure — the caller requested the cancellation.","triggerScenarios":"Passing cancel_callback=lambda: True (or one that flips to True after the user clicks Stop) into prepare_s3_dataset_download; the exception surfaces at the next callback checkpoint — during listing or between object downloads.","commonSituations":"UI 'Cancel' button wired to a flag the download polls; job orchestration cancelling a queued training run; timeouts implemented by the caller via a deadline-based callback.","solutions":["Catch S3DownloadCancelled explicitly in the caller and treat it as a normal cancellation (stop the workflow, clean the temp dir via the returned object's cleanup() or your own dest_dir).","If the cancellation was unintended, fix the callback's state — e.g. a shared flag that a previous failed run left set to True.","Reset/clear the cancel flag before starting a new download."],"exampleFix":"// before\ntry:\n    dl = prepare_s3_dataset_download(cfg, cancel_callback=cb)\nexcept RuntimeError as e:  # swallows cancellation as generic failure\n    log.error(e)\n// after\nfrom core.training.s3_dataset import S3DownloadCancelled\ntry:\n    dl = prepare_s3_dataset_download(cfg, cancel_callback=cb)\nexcept S3DownloadCancelled:\n    log.info(\"Download cancelled by user\")\n    return","handlingStrategy":"try-catch","validationCode":"if cancel_callback is not None and cancel_callback():\n    # skip the call entirely — user already cancelled\n    return None","typeGuard":null,"tryCatchPattern":"from core.training.s3_dataset import S3DownloadCancelled\n\ntry:\n    dl = prepare_s3_dataset_download(cfg, cancel_callback=cb)\nexcept S3DownloadCancelled:\n    # expected control flow: abort the training job cleanly\n    abort_job(reason='download_cancelled')\n    return","preventionTips":["Catch S3DownloadCancelled separately from generic RuntimeError.","Reset the cancel flag before each new download attempt.","Wire the cancel flag to the UI action once, and clear it on job teardown."],"tags":["s3","cancellation","control-flow","dataset"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}