{"record":{"id":"38030901e8e91ad9","repo":"unslothai/unsloth","slug":"dataset-path-may-not-contain-null-bytes-380309","errorCode":null,"errorMessage":"dataset path may not contain null bytes","messagePattern":"dataset path may not contain null bytes","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/paths/storage_roots.py","lineNumber":499,"sourceCode":"    return resolve_under_root(\n        path_value,\n        root = exports_root(),\n        strip_prefixes = (\"exports\",),\n    )\n\n\ndef resolve_tensorboard_dir(path_value: str | None = None) -> Path:\n    return resolve_under_root(\n        path_value,\n        root = tensorboard_root(),\n        strip_prefixes = (\"runs\", \"tensorboard\"),\n    )\n\n\ndef resolve_dataset_path(path_value: str) -> Path:\n    raw = str(path_value or \"\").strip()\n    if \"\\x00\" in raw:\n        raise ValueError(\"dataset path may not contain null bytes\")\n    path = Path(raw).expanduser()\n    if \"..\" in path.parts:\n        raise ValueError(f\"dataset path may not contain '..' segments: {raw!r}\")\n    if path.is_absolute():\n        for root_fn in (datasets_root, dataset_uploads_root, recipe_datasets_root):\n            try:\n                _assert_contained(path, root_fn())\n                return path\n            except ValueError:\n                continue\n        raise ValueError(f\"dataset path must be relative or under a dataset root: {raw!r}\")\n\n    parts = [part for part in Path(path_value).parts if part not in (\"\", \".\")]\n    if parts[:2] == [\"assets\", \"datasets\"]:\n        parts = parts[2:]\n    if parts and parts[0] == \"uploads\":\n        cleaned = Path(*parts[1:]) if len(parts) > 1 else Path()\n        return dataset_uploads_root() / cleaned","sourceCodeStart":481,"sourceCodeEnd":517,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/paths/storage_roots.py#L481-L517","documentation":"Raised by resolve_dataset_path() in the studio backend when the supplied dataset path string contains a null byte (\\x00). Null bytes are rejected up-front because they cannot form a valid filesystem path and can be used to truncate or confuse path-handling code downstream. This is an input-validation ValueError that fires before any filesystem access happens.","triggerScenarios":"Calling resolve_dataset_path(path_value) where path_value (after str() and .strip()) contains a literal '\\x00' character — e.g. a value read from a binary-polluted request body, a truncated C string, or a crafted API payload like 'data\\x00.csv'.","commonSituations":"Malformed client input passed through an HTTP API, data copied from binary sources, or test fixtures that embed escape sequences. Also seen when a frontend sends a string that was never sanitized after decoding a byte buffer containing embedded nulls.","solutions":["Sanitize or reject the input string at the API boundary before calling resolve_dataset_path (strip or refuse '\\x00').","Inspect the caller that produced the path value (request parsing, DB column, config file) and fix the encoding/truncation bug upstream.","If the null byte is legitimate data noise, strip it: path_value.replace('\\x00', '') before resolution — only if truncation semantics are acceptable for your app."],"exampleFix":"// before\nconst p = rawBuffer.toString('utf-8'); // may contain \\x00\nresolve_dataset_path(p);\n\n// after\nconst p = rawBuffer.toString('utf-8').replace(/\\x00/g, '');\nif (!p) throw new Error('empty dataset path');\nresolve_dataset_path(p);","handlingStrategy":"validation","validationCode":"def safe_dataset_path(raw: str) -> str:\n    if '\\x00' in (raw or ''):\n        raise ValueError('dataset path contains null bytes')\n    return raw.strip()\n\nresolve_dataset_path(safe_dataset_path(user_input))","typeGuard":null,"tryCatchPattern":"try:\n    path = resolve_dataset_path(raw)\nexcept ValueError as e:\n    if 'null bytes' in str(e):\n        return bad_request('dataset path contains null bytes')  # client bug, do not retry\n    raise","preventionTips":["Sanitize all path inputs at the API boundary: strip \\x00 before they reach the resolver.","Treat null bytes in strings from byte-decoded sources as a red flag for upstream truncation bugs."],"tags":["validation","path-traversal","input-sanitization","python"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}