{"record":{"id":"c7cd7254d4b615ec","repo":"unslothai/unsloth","slug":"hf-dataset-must-not-contain","errorCode":null,"errorMessage":"hf_dataset must not contain '..'","messagePattern":"hf_dataset must not contain '\\.\\.'","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"studio/backend/models/training.py","lineNumber":235,"sourceCode":"            and self.dataset_slice_end < self.dataset_slice_start\n        ):\n            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","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/training.py#L217-L253","documentation":"Raised by the _check_hf_dataset field validator: the dataset id must not contain '..' anywhere in the string. This is a path-traversal guard — the id is used to construct Hub paths, and '..' segments could escape the expected directory. It runs after the 256-char cap and before per-segment regex validation.","triggerScenarios":"POST a training start request with hf_dataset containing '..', e.g. 'user/../other/dataset' or 'data/../..'.","commonSituations":"Path-mangling code that tries to normalize or join the dataset id like a filesystem path; user input containing dot-dot from a file browser; test payloads deliberately probing traversal.","solutions":["Send a plain 'owner/dataset' id with no dot-dot sequences.","Remove any path normalization (os.path.join/realpath) applied to dataset ids in your client.","Sanitize user input by rejecting strings containing '..' before submit."],"exampleFix":"# before\nhf_dataset = str(Path(base) / rel)  # may produce '..'\n# after\nhf_dataset = rel  # plain 'owner/dataset' id","handlingStrategy":"validation","validationCode":"def dataset_id_no_dotdot(body: dict) -> bool:\n    return \"..\" not in (body.get(\"hf_dataset\") or \"\")","typeGuard":"function noDotDot(id: string): boolean {\n  return !id.includes('..');\n}","tryCatchPattern":null,"preventionTips":["Never run filesystem path normalization on dataset ids","Treat dataset ids as opaque identifiers"],"tags":["pydantic","validation","training","path-traversal","security"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}