{"record":{"id":"27a04a5a521d8b99","repo":"unslothai/unsloth","slug":"each-repo-must-be-owner-name-got-r-r","errorCode":null,"errorMessage":"Each repo must be `owner/name`; got {r!r}","messagePattern":"Each repo must be `owner/name`; got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/plugins/data-designer-github-repo-seed/src/data_designer_github_repo_seed/config.py","lineNumber":49,"sourceCode":"        le = 5000,\n        description = \"Maximum items per repo per item type (e.g. limit=100 + ['issues','pulls'] => up to 200 items per repo).\",\n    )\n    include_comments: bool = Field(\n        default = True,\n        description = \"Fetch the first N comments of each issue/PR and include them in the `comments` column.\",\n    )\n    max_comments_per_item: int = Field(default = 30, ge = 0, le = 200)\n\n    @field_validator(\"repos\")\n    @classmethod\n    def _validate_repos(cls, v: list[str]) -> list[str]:\n        out: list[str] = []\n        for r in v or []:\n            r = r.strip()\n            if not r:\n                continue\n            if r.count(\"/\") != 1 or not all(r.split(\"/\")):\n                raise ValueError(f\"Each repo must be `owner/name`; got {r!r}\")\n            out.append(r)\n        return out\n\n    @field_validator(\"item_types\")\n    @classmethod\n    def _validate_item_types(cls, v: list[str]) -> list[str]:\n        if not v:\n            raise ValueError(\"item_types must not be empty\")\n        return list(dict.fromkeys(v))\n\n    @model_validator(mode = \"after\")\n    def _ensure_repos(self) -> \"GitHubRepoSeedSource\":\n        if not self.repos:\n            raise ValueError(\"At least one repo is required\")\n        return self\n","sourceCodeStart":31,"sourceCodeEnd":65,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/plugins/data-designer-github-repo-seed/src/data_designer_github_repo_seed/config.py#L31-L65","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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).","solutions":["Use the plain 'owner/name' slug for every repos entry, e.g. 'huggingface/transformers'.","Strip URLs down to slug form: 'https://github.com/owner/name' -> 'owner/name'.","Remove branch/subtree suffixes ('owner/name/tree/main') — the scraper takes branches via other config fields, not the repo string."],"exampleFix":"# before\nrepos = [\"https://github.com/huggingface/transformers\"]\n\n# after\nrepos = [\"huggingface/transformers\"]","handlingStrategy":"validation","validationCode":"import re\n\nREPO_SLUG = re.compile(r\"^[^/\\s]+/[^/\\s]+$\")\n\ndef is_repo_slug(s: str) -> bool:\n    s = s.strip()\n    return bool(REPO_SLUG.fullmatch(s))\n\ndef to_slug(url_or_slug: str) -> str:\n    # 'https://github.com/o/r' -> 'o/r'; passes plain slugs through\n    m = re.search(r\"github\\.com/([^/\\s]+/[^/\\s]+)\", url_or_slug)\n    return m.group(1).rstrip(\"/\") if m else url_or_slug.strip()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Normalize pasted URLs to owner/name slugs before storing them in config.","Validate the repos list client-side with the same single-slash rule."],"tags":["pydantic","github","config","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}