{"record":{"id":"282d093889d8e72e","repo":"unslothai/unsloth","slug":"hf-dataset-contains-invalid-characters-or-path-seg","errorCode":null,"errorMessage":"hf_dataset contains invalid characters or path segments","messagePattern":"hf_dataset contains invalid characters or path segments","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"studio/backend/models/training.py","lineNumber":237,"sourceCode":"            raise ValueError(\n                \"dataset_slice_end must be greater than or equal to dataset_slice_start\"\n            )\n        return self\n\n    @field_validator(\"hf_dataset\")\n    @classmethod\n    def _check_hf_dataset(cls, v: Optional[str]) -> Optional[str]:\n        if v is None:\n            return v\n        v = v.strip()\n        if not v:\n            return None\n        if len(v) > 256:\n            raise ValueError(\"hf_dataset is too long (max 256 chars)\")\n        if \"..\" in v:\n            raise ValueError(\"hf_dataset must not contain '..'\")\n        if any(_HF_DATASET_ID_SEGMENT_RE.fullmatch(segment) is None for segment in v.split(\"/\")):\n            raise ValueError(\"hf_dataset contains invalid characters or path segments\")\n        return v\n\n    @field_validator(\"subset\")\n    @classmethod\n    def _check_subset(cls, v: Optional[str]) -> Optional[str]:\n        if v is None:\n            return v\n        v = v.strip()\n        if not v:\n            return None\n        if len(v) > MAX_HF_DATASET_OPTION_LENGTH:\n            raise ValueError(f\"subset is too long (max {MAX_HF_DATASET_OPTION_LENGTH} chars)\")\n        if not valid_hf_dataset_config_name(v):\n            raise ValueError(\"subset contains invalid characters\")\n        return v\n\n    @field_validator(\n        \"model_local_path\",","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/training.py#L219-L255","documentation":"Raised by the _check_hf_dataset field validator: the dataset id is split on '/' and every segment must fullmatch the _HF_DATASET_ID_SEGMENT_RE pattern (Hugging Face id character rules). This catches invalid characters, empty segments from leading/trailing/double slashes, and malformed segments, after the length and '..' checks. The regex runs per-segment, so 'user//data' fails on the empty middle segment.","triggerScenarios":"POST a training start request with hf_dataset like 'user//data' (double slash), '/user/data' (leading slash), 'user/data/' (trailing slash — though trailing whitespace is stripped first), or segments containing spaces, colons, or other characters outside the HF id charset.","commonSituations":"Programmatic string concatenation with an unexpected slash; URLs pasted and only partially cleaned; ids built from user handles containing whitespace or unicode; copy-paste artifacts like non-breaking spaces.","solutions":["Send a clean 'owner/dataset' (or single 'dataset') id with only valid HF id characters per segment.","Normalize client-side: strip, collapse duplicate slashes, drop leading/trailing slashes, then validate each segment against the same rules.","If the id came from a URL, parse it properly instead of string-replacing prefixes."],"exampleFix":"// before\n{ hf_dataset: \"/user/data/\" }\n// after\n{ hf_dataset: \"user/data\" }","handlingStrategy":"validation","validationCode":"import re\n_HF_SEGMENT = re.compile(r\"^[A-Za-z0-9][A-Za-z0-9._-]*$\")\n\ndef dataset_segments_valid(body: dict) -> bool:\n    v = (body.get(\"hf_dataset\") or \"\").strip()\n    return v != \"\" and all(_HF_SEGMENT.fullmatch(seg) for seg in v.split(\"/\"))","typeGuard":"const HF_SEGMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\nfunction segmentsValid(id: string): boolean {\n  return id.trim().split('/').every(s => HF_SEGMENT.test(s));\n}","tryCatchPattern":null,"preventionTips":["Parse HF URLs with a URL parser, not string replace","Collapse duplicate/leading/trailing slashes before sending","Offer a searchable dataset picker instead of free text"],"tags":["pydantic","validation","training","huggingface","dataset","sanitization"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}