{"record":{"id":"a0d4ae8ff80adf49","repo":"mislav/hub","slug":"invalid-github-url-s","errorCode":null,"errorMessage":"Invalid GitHub URL: %s","messagePattern":"Invalid GitHub URL: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"github/project.go","lineNumber":125,"sourceCode":"func NewProjectFromRepo(repo *Repository) (p *Project, err error) {\n\turl, err := url.Parse(repo.HTMLURL)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tp, err = NewProjectFromURL(url)\n\treturn\n}\n\nfunc NewProjectFromURL(url *url.URL) (p *Project, err error) {\n\tif !knownGitHubHostsInclude(url.Host) {\n\t\terr = &HostError{url}\n\t\treturn\n\t}\n\n\tparts := strings.SplitN(url.Path, \"/\", 4)\n\tif len(parts) <= 2 {\n\t\terr = fmt.Errorf(\"Invalid GitHub URL: %s\", url)\n\t\treturn\n\t}\n\n\tname := strings.TrimSuffix(parts[2], \".git\")\n\tp = newProject(parts[1], name, url.Host, url.Scheme)\n\n\treturn\n}\n\nfunc NewProject(owner, name, host string) *Project {\n\treturn newProject(owner, name, host, \"\")\n}\n\nfunc newProject(owner, name, host, protocol string) *Project {\n\tif strings.Contains(owner, \"/\") {\n\t\tresult := strings.SplitN(owner, \"/\", 2)\n\t\towner = result[0]\n\t\tif name == \"\" {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/github/project.go#L107-L143","documentation":"NewProjectFromURL(url) splits url.Path into at most 4 segments and expects at least 3 (\"\", owner, name). If the path has 2 or fewer segments it cannot extract owner/name and returns this error. It guards against URLs that are hosts or bare root paths rather than repository URLs.","triggerScenarios":"Calling NewProjectFromURL with a URL whose path lacks owner/name, e.g. https://github.com, https://github.com/, or https://github.com/owner (called from findPushTarget, NewProjectFromRepo, Project, ParseURL when a remote URL is malformed or truncated).","commonSituations":"Remote URL set to just the host (e.g. git remote add origin https://github.com); truncated URL after a bad copy/paste; url.<base>.insteadOf rewrite producing a bare base URL; git:// or ssh URLs with empty path after parsing.","solutions":["Fix the remote URL to the full form host/owner/repo(.git): git remote set-url origin https://github.com/owner/repo.git","Validate the URL shape before calling: URL.Path must contain /owner/name","If a git config insteadOf rewrite is mangling the URL, correct `git config --get-regexp url`","Re-enter the repository URL from `git remote -v` output to fix truncation"],"exampleFix":"// before\ngit remote add origin https://github.com\np, err := NewProjectFromURL(u) // Invalid GitHub URL\n// after\ngit remote set-url origin https://github.com/owner/repo.git\np, err := NewProjectFromURL(u) // OK","handlingStrategy":"validation","validationCode":"func isRepoURL(raw string) bool {\n    u, err := url.Parse(raw)\n    if err != nil { return false }\n    parts := strings.SplitN(u.Path, \"/\", 4)\n    return len(parts) > 2 && parts[1] != \"\" && parts[2] != \"\"\n}","typeGuard":null,"tryCatchPattern":"p, err := github.NewProjectFromURL(u)\nif err != nil {\n    if strings.Contains(err.Error(), \"Invalid GitHub URL\") {\n        return nil, fmt.Errorf(\"URL %q lacks owner/name segments\", u)\n    }\n    return nil, err\n}","preventionTips":["Validate remote URLs contain /owner/name before use","Never set a remote URL to just the host base","Check git config url.<base>.insteadOf rules that rewrite paths to bare bases","Copy full clone URLs (ending in owner/repo) rather than base URLs"],"tags":["url-parsing","github","remote-configuration"],"backgroundTag":"invalid-github-url","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}