{"record":{"id":"e400a34e53c2eda9","repo":"unslothai/unsloth","slug":"no-images-found-in-entry-repo","errorCode":null,"errorMessage":"No images found in '{entry['repo']}'.","messagePattern":"No images found in '(.+?)'\\.","errorType":"http","errorClass":"HTTPException","httpStatus":502,"severity":"error","filePath":"studio/backend/routes/training.py","lineNumber":4277,"sourceCode":"                    except OSError:\n                        # Best effort: one unrestorable entry must not mask the original failure.\n                        pass\n\n            try:\n                try:\n                    if entry[\"loader\"] == \"imagefolder_jsonl\":\n                        imported = _materialize_imagefolder_jsonl(entry, staging, cap)\n                    else:\n                        imported = _materialize_hf_dataset(entry, staging, cap)\n                except HTTPException:\n                    raise\n                except Exception as e:  # noqa: BLE001 -- surface a readable fetch/parse failure\n                    raise HTTPException(\n                        status_code = 502,\n                        detail = f\"Could not import '{entry['repo']}': {e}\",\n                    )\n                if imported == 0:\n                    raise HTTPException(\n                        status_code = 502,\n                        detail = f\"No images found in '{entry['repo']}'.\",\n                    )\n                # Promote the fully-materialized staging dir as a UNIT: a same-filesystem rename is atomic, so a hard process death\n                # leaves either the old folder or the finished import. rmdir needs an empty target, so fold any pre-existing files (a .thumbs cache, an older metadata.jsonl) INTO staging first and keep one atomic promotion.\n                try:\n                    for p in sorted(folder.iterdir()):\n                        # Same name in both: the imported file wins, as the previous per-file move did. Park the old one in the rescue dir so the folder can be emptied for the rename without destroying it.\n                        dest = (rescue if (staging / p.name).exists() else staging) / p.name\n                        shutil.move(str(p), str(dest))\n                        folded.append((dest, p))\n                    os.rmdir(folder)\n                    os.replace(str(staging), str(folder))\n                except (OSError, shutil.Error) as e:\n                    # Every step here can fail (an unmovable entry, a folder that gained a file, a rename held by antivirus), and by then the folder's entries live only in the staging/rescue dirs the finally deletes.\n                    restore_folded()\n                    raise HTTPException(\n                        status_code = 409,","sourceCodeStart":4259,"sourceCodeEnd":4295,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/training.py#L4259-L4295","documentation":"HTTP 502 from the import route: materialization completed without exceptions but wrote zero images (imported == 0) — every row was skipped (null image column values) or the source was empty. The empty staging dir is discarded; the existing dataset folder is untouched.","triggerScenarios":"Importing an example whose upstream rows all have null in the image column, or whose split/config resolves to an empty set. E.g. a repo revision where all image cells are null, or cap=0 misconfiguration.","commonSituations":"Upstream datasets with sparse image columns that became fully null after a revision; split names changing so the selected split is empty; curated entry pointing at a deprecated revision.","solutions":["Pick a different example dataset or retry later (upstream may be mid-migration).","Verify the repo manually: load a few rows and check the image column is non-null.","If curating locally, point the example at a known-good revision (revision= pin)."],"exampleFix":"from itertools import islice\nfrom datasets import load_dataset\nrows = list(islice(load_dataset('user/repo', streaming=True), 5))\nnonnull = sum(r['image'] is not None for r in rows)\nprint(nonnull, 'of', len(rows), 'rows have images')","handlingStrategy":"validation","validationCode":"from itertools import islice\nfrom datasets import load_dataset\n\ndef example_has_images(repo: str) -> bool:\n    rows = list(islice(load_dataset(repo, streaming=True), 5))\n    return bool(rows) and any(\n        any(isinstance(v, dict) and v.get('bytes', v.get('path')) for v in r.values())\n        for r in rows\n    )","typeGuard":"def is_empty_import(exc: HTTPException) -> bool:\n    return exc.status_code == 502 and 'No images found' in str(exc.detail)","tryCatchPattern":"try:\n    await api.importExample(ex.id)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 502 and 'No images found' in e.response.text:\n        pick_another_example()  # all-null upstream; retrying same id will fail again\n    else:\n        raise","preventionTips":["Smoke-test curated repos (5 rows, image column non-null) before shipping curated entries.","Pin curated repos to revisions known to have populated image columns."],"tags":["huggingface","upstream","import","http-502","empty-data"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}