unslothai/unsloth · error · RecipeDatasetPublishError

This execution artifact is outside the Recipe Studio dataset

Error message

This execution artifact is outside the Recipe Studio dataset storage.

What it means

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.

Source

Thrown at studio/backend/core/data_recipe/huggingface.py:32

)
_UNSLOTH_STUDIO_FOOTER = (
    '<sub style="white-space: nowrap;">Made with ❤️ using 🦥 ' "Unsloth Studio</sub>"
)


class RecipeDatasetPublishError(ValueError):
    """Raised when a recipe dataset cannot be published to Hugging Face."""


def _resolve_recipe_artifact_path(artifact_path: str) -> Path:
    root = recipe_datasets_root().expanduser().resolve()
    candidate = resolve_dataset_path(artifact_path).expanduser()
    resolved = candidate.resolve(strict = False)

    try:
        resolved.relative_to(root)
    except ValueError as exc:
        raise RecipeDatasetPublishError(
            "This execution artifact is outside the Recipe Studio dataset storage."
        ) from exc

    if not resolved.exists():
        raise RecipeDatasetPublishError("Execution artifacts are no longer available.")
    if not resolved.is_dir():
        raise RecipeDatasetPublishError("Execution artifact path is not a dataset folder.")

    return resolved


def publish_recipe_dataset(
    *,
    artifact_path: str,
    repo_id: str,
    description: str,
    hf_token: str | None = None,
    private: bool = False,

View on GitHub (pinned to 203007d190)

Solutions

  1. Use the exact artifact_path value the recipe execution response returned, not a hand-built one.
  2. Check the configured Recipe Studio datasets root and ensure the artifact lives beneath it.
  3. Remove symlinks inside artifact paths that point outside the storage root.
  4. If storage was relocated, re-run the recipe so artifacts land in the current root.

Example fix

# before
publish_recipe_dataset(artifact_path="/tmp/my-run/output", repo_id="user/ds")

# after
run = execute_recipe(recipe)
publish_recipe_dataset(artifact_path=run["artifact_path"], repo_id="user/ds")
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
def artifact_inside_root(artifact_path: str, root: Path) -> bool:
    try:
        Path(artifact_path).expanduser().resolve(strict=False).relative_to(root.expanduser().resolve())
        return True
    except ValueError:
        return False

Try / catch

try:
    publish_recipe_dataset(artifact_path=p, repo_id=r)
except RecipeDatasetPublishError as e:
    if 'outside the Recipe Studio dataset storage' in str(e):
        p = fetch_artifact_path_from_run(run_id)  # use the server-provided path

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/bb826517844c45a7. Report an issue: GitHub.