{"record":{"id":"4941cca9ffbcb198","repo":"unslothai/unsloth","slug":"subset-contains-invalid-characters","errorCode":null,"errorMessage":"subset contains invalid characters","messagePattern":"subset contains invalid characters","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"studio/backend/models/training.py","lineNumber":251,"sourceCode":"            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\",\n        \"dataset_local_path\",\n        \"model_snapshot_path\",\n        \"dataset_snapshot_path\",\n    )\n    @classmethod\n    def _check_cache_local_path(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) > 4096:\n            raise ValueError(\"local cache path is too long (max 4096 chars)\")\n        if \"\\x00\" in v:","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/training.py#L233-L269","documentation":"Raised by the _check_subset field validator: after the length cap, the subset must satisfy valid_hf_dataset_config_name(), the Hugging Face config-name charset rules. This rejects spaces, slashes, colons, and other characters that are not legal in an HF dataset config name. It is the subset analogue of the per-segment regex applied to hf_dataset.","triggerScenarios":"POST a training start request with a subset containing invalid characters, e.g. 'my subset', 'config/v2', 'train:latest', or a URL fragment.","commonSituations":"Free-text UI input without charset validation; deriving subset from filenames with spaces; copying values from YAML keys that contain colons.","solutions":["Use a plain config name matching HF rules (typically letters, digits, dash, underscore, dot), e.g. 'plain_text'.","List the dataset's real configs via the HF API and present them as a dropdown instead of free text.","Slugify user input client-side before sending."],"exampleFix":"// before\n{ subset: \"My Config (v2)\" }\n// after\n{ subset: \"my-config-v2\" }","handlingStrategy":"validation","validationCode":"import re\n_CONFIG_NAME = re.compile(r\"^[A-Za-z0-9][A-Za-z0-9._-]*$\")\n\ndef subset_chars_valid(body: dict) -> bool:\n    v = (body.get(\"subset\") or \"\").strip()\n    return v == \"\" or bool(_CONFIG_NAME.fullmatch(v))","typeGuard":"const CONFIG_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\nfunction subsetCharsOk(subset: string | undefined): boolean {\n  const v = subset?.trim() ?? '';\n  return v === '' || CONFIG_NAME.test(v);\n}","tryCatchPattern":null,"preventionTips":["Slugify free-text config names before sending","Prefer enum/dropdown of real configs over typed input"],"tags":["pydantic","validation","training","huggingface","subset","sanitization"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}