{"record":{"id":"bb826517844c45a7","repo":"unslothai/unsloth","slug":"this-execution-artifact-is-outside-the-recipe-stud","errorCode":null,"errorMessage":"This execution artifact is outside the Recipe Studio dataset storage.","messagePattern":"This execution artifact is outside the Recipe Studio dataset storage\\.","errorType":"exception","errorClass":"RecipeDatasetPublishError","httpStatus":400,"severity":"error","filePath":"studio/backend/core/data_recipe/huggingface.py","lineNumber":32,"sourceCode":")\n_UNSLOTH_STUDIO_FOOTER = (\n    '<sub style=\"white-space: nowrap;\">Made with ❤️ using 🦥 ' \"Unsloth Studio</sub>\"\n)\n\n\nclass RecipeDatasetPublishError(ValueError):\n    \"\"\"Raised when a recipe dataset cannot be published to Hugging Face.\"\"\"\n\n\ndef _resolve_recipe_artifact_path(artifact_path: str) -> Path:\n    root = recipe_datasets_root().expanduser().resolve()\n    candidate = resolve_dataset_path(artifact_path).expanduser()\n    resolved = candidate.resolve(strict = False)\n\n    try:\n        resolved.relative_to(root)\n    except ValueError as exc:\n        raise RecipeDatasetPublishError(\n            \"This execution artifact is outside the Recipe Studio dataset storage.\"\n        ) from exc\n\n    if not resolved.exists():\n        raise RecipeDatasetPublishError(\"Execution artifacts are no longer available.\")\n    if not resolved.is_dir():\n        raise RecipeDatasetPublishError(\"Execution artifact path is not a dataset folder.\")\n\n    return resolved\n\n\ndef publish_recipe_dataset(\n    *,\n    artifact_path: str,\n    repo_id: str,\n    description: str,\n    hf_token: str | None = None,\n    private: bool = False,","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/data_recipe/huggingface.py#L14-L50","documentation":"RecipeDatasetPublishError (ValueError) raised by _resolve_recipe_artifact_path when the resolved execution-artifact path does not lie under the Recipe Studio datasets root. The check uses Path.relative_to on the fully resolved paths, so symlinks and .. segments are unfolded before comparison; anything escaping the root (absolute path elsewhere, traversal, or a symlink pointing out) is rejected before any Hugging Face upload happens.","triggerScenarios":"Passing artifact_path='/etc' or another absolute location outside the datasets root; a relative path containing .. that resolves above the root; an artifact directory that is itself a symlink whose target sits outside the root; resolve_dataset_path mapping the input to a different storage area.","commonSituations":"Clients hand-crafting artifact_path strings instead of using the path returned by the recipe execution API; moving dataset storage or changing the configured root while clients keep old paths; symlinked artifact dirs created by external tooling.","solutions":["Use the exact artifact_path value the recipe execution response returned, not a hand-built one.","Check the configured Recipe Studio datasets root and ensure the artifact lives beneath it.","Remove symlinks inside artifact paths that point outside the storage root.","If storage was relocated, re-run the recipe so artifacts land in the current root."],"exampleFix":"# before\npublish_recipe_dataset(artifact_path=\"/tmp/my-run/output\", repo_id=\"user/ds\")\n\n# after\nrun = execute_recipe(recipe)\npublish_recipe_dataset(artifact_path=run[\"artifact_path\"], repo_id=\"user/ds\")","handlingStrategy":"validation","validationCode":"from pathlib import Path\ndef artifact_inside_root(artifact_path: str, root: Path) -> bool:\n    try:\n        Path(artifact_path).expanduser().resolve(strict=False).relative_to(root.expanduser().resolve())\n        return True\n    except ValueError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    publish_recipe_dataset(artifact_path=p, repo_id=r)\nexcept RecipeDatasetPublishError as e:\n    if 'outside the Recipe Studio dataset storage' in str(e):\n        p = fetch_artifact_path_from_run(run_id)  # use the server-provided path","preventionTips":["Always use the artifact_path returned by the execution API.","Mirror the server's root check client-side before calling publish.","Avoid symlinks inside the datasets root that point outside it."],"tags":["validation","path-traversal","huggingface","data-recipe","studio"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}