unslothai/unsloth · error · ValueError

Each repo must be `owner/name`; got {r!r}

Error message

Each repo must be `owner/name`; got {r!r}

What it means

Field validator _validate_repos on the GitHub repo seed source config (GitHubRepoSeedSource). Each entry in repos must be exactly 'owner/name': exactly one slash with non-empty parts on both sides. Entries are trimmed and blanks are skipped; anything else (two slashes, leading/trailing slash, empty owner or name) raises with the offending value.

Source

Thrown at studio/backend/plugins/data-designer-github-repo-seed/src/data_designer_github_repo_seed/config.py:49

        le = 5000,
        description = "Maximum items per repo per item type (e.g. limit=100 + ['issues','pulls'] => up to 200 items per repo).",
    )
    include_comments: bool = Field(
        default = True,
        description = "Fetch the first N comments of each issue/PR and include them in the `comments` column.",
    )
    max_comments_per_item: int = Field(default = 30, ge = 0, le = 200)

    @field_validator("repos")
    @classmethod
    def _validate_repos(cls, v: list[str]) -> list[str]:
        out: list[str] = []
        for r in v or []:
            r = r.strip()
            if not r:
                continue
            if r.count("/") != 1 or not all(r.split("/")):
                raise ValueError(f"Each repo must be `owner/name`; got {r!r}")
            out.append(r)
        return out

    @field_validator("item_types")
    @classmethod
    def _validate_item_types(cls, v: list[str]) -> list[str]:
        if not v:
            raise ValueError("item_types must not be empty")
        return list(dict.fromkeys(v))

    @model_validator(mode = "after")
    def _ensure_repos(self) -> "GitHubRepoSeedSource":
        if not self.repos:
            raise ValueError("At least one repo is required")
        return self

View on GitHub (pinned to 203007d190)

Solutions

  1. Use the plain 'owner/name' slug for every repos entry, e.g. 'huggingface/transformers'.
  2. Strip URLs down to slug form: 'https://github.com/owner/name' -> 'owner/name'.
  3. Remove branch/subtree suffixes ('owner/name/tree/main') — the scraper takes branches via other config fields, not the repo string.

Example fix

# before
repos = ["https://github.com/huggingface/transformers"]

# after
repos = ["huggingface/transformers"]
Defensive patterns

Strategy: validation

Validate before calling

import re

REPO_SLUG = re.compile(r"^[^/\s]+/[^/\s]+$")

def is_repo_slug(s: str) -> bool:
    s = s.strip()
    return bool(REPO_SLUG.fullmatch(s))

def to_slug(url_or_slug: str) -> str:
    # 'https://github.com/o/r' -> 'o/r'; passes plain slugs through
    m = re.search(r"github\.com/([^/\s]+/[^/\s]+)", url_or_slug)
    return m.group(1).rstrip("/") if m else url_or_slug.strip()

Prevention

When it happens

Trigger: Configuring the data-designer-github-repo-seed plugin with a repos entry like 'https://github.com/owner/name', 'owner/name/tree/main', 'owner/', '/name', or 'owner/name/subdir'.

Common situations: Pasting full GitHub URLs instead of the slug; including branch/path suffixes; trailing whitespace-only entries are tolerated but stray commas in YAML/JSON produce malformed entries like 'owner','name' split into separate list items (those fail the single-slash check).

Related errors


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