{"record":{"id":"c2be2403323260c1","repo":"mislav/hub","slug":"error-that-fork-is-not-available-anymore","errorCode":null,"errorMessage":"Error: that fork is not available anymore","messagePattern":"Error: that fork is not available anymore","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"commands/merge.go","lineNumber":84,"sourceCode":"\tpullRequest, err := gh.PullRequest(url.Project, id)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trepo, err := github.LocalRepo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tremote, err := repo.RemoteForRepo(pullRequest.Base.Repo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbranch := pullRequest.Head.Ref\n\theadRepo := pullRequest.Head.Repo\n\tif headRepo == nil {\n\t\treturn fmt.Errorf(\"Error: that fork is not available anymore\")\n\t}\n\n\targs.Before(\"git\", \"fetch\", remote.Name, fmt.Sprintf(\"refs/pull/%s/head\", id))\n\n\t// Remove pull request URL\n\tidx := args.IndexOfParam(mergeURL)\n\targs.RemoveParam(idx)\n\n\tmergeMsg := fmt.Sprintf(\"Merge pull request #%s from %s/%s\\n\\n%s\", id, headRepo.Owner.Login, branch, pullRequest.Title)\n\targs.AppendParams(\"FETCH_HEAD\", \"-m\", mergeMsg)\n\n\tif args.IndexOfParam(\"--ff-only\") == -1 && args.IndexOfParam(\"--squash\") == -1 && args.IndexOfParam(\"--ff\") == -1 {\n\t\ti := args.IndexOfParam(\"-m\")\n\t\targs.InsertParam(i, \"--no-ff\")\n\t}\n\n\treturn nil\n}","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/commands/merge.go#L66-L102","documentation":"When merging a pull request given by URL/number, `transformMergeArgs` fetches the PR and reads its head repository. If `pullRequest.Head.Repo` is nil, the fork backing the PR head has been deleted, so the branch can no longer be fetched. The command aborts before attempting `git fetch` on a nonexistent repo.","triggerScenarios":"Running `gh merge <pr-url-or-number>` where the fetched `github.PullRequest.Head.Repo` is nil — the contributor's fork was deleted (or the repo was made private/removed) after the PR was opened.","commonSituations":"Long-lived PRs whose author deleted their fork after closing other work; organizations that clean up contributor forks; PRs from branches on repos removed due to policy or inactivity.","solutions":["Ask the PR author to restore their fork and reopen/refresh the PR.","Have the author re-open a new PR from an existing branch/repo containing the same changes.","Apply the changes manually (cherry-pick from a local clone of the fork if you have one) and merge via a new local branch.","Close the PR if the changes are unavailable."],"exampleFix":"// before\ngh merge https://github.com/owner/repo/pull/123   // Head.Repo is nil\n// after\n# ask author to restore fork, then retry, or locally:\ngit remote add fork git@github.com:author/fork.git && git fetch fork branch && git merge fork/branch","handlingStrategy":"try-catch","validationCode":"pr := fetchPullRequest(id)\nif pr.Head.Repo == nil {\n    fmt.Fprintln(os.Stderr, \"PR head fork is gone; ask the author to restore it or merge manually\")\n    os.Exit(1)\n}","typeGuard":"func headRepoAvailable(pr *github.PullRequest) bool {\n    return pr.Head != nil && pr.Head.Repo != nil\n}","tryCatchPattern":"err := runMerge(prNumber)\nif err != nil && strings.Contains(err.Error(), \"not available anymore\") {\n    // recover: add fork remote manually or cherry-pick into a local branch\n    fmt.Fprintln(os.Stderr, \"fork deleted; falling back to manual merge\")\n}","preventionTips":["Merge PRs promptly; forks may be deleted over time.","Ask contributors not to delete forks with open PRs.","Detect nil Head.Repo before attempting `git fetch` of the head ref.","Keep a local clone of important fork branches as a backup."],"tags":["pull-request","fork-deleted","github-api"],"backgroundTag":"fork-source-deleted","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}