Repository: cli/cli

Issue:
PR Create lost the ability to ask review from teams
### Describe the bug

`gh pr create` does not list teams anymore for reviewers 


### Affected version

[GitHub CLI 2.76.1](https://github.com/cli/cli/releases/tag/v2.76.1)


### Steps to reproduce the behavior

While creating PRs when selecting reviewers I used to see all internal teams/groups and directly ask for review from a group/team easily. With the latest version I am not seeing any teams in the list and only individual members. 

### Expected vs actual behavior

Being able to see all teams in the org that has access to the repo .


Discussion:
@andyfeller: Thank you for opening this issue and sincere apologies for the friction, @gcg! 🙇 

This is definitely a regression on our part and I'm hard at work understanding the problems that emerged in https://github.com/cli/cli/issues/11360 that affected `gh pr create`.

<details>
<summary>
  <b><code>gh pr create</code> in v2.72.0 presented organization teams in interactive mode</b>
</summary>
<p>

From `v2.72.0`:

```shell
$ gh pr create
Warning: 1 uncommitted change
? Where should we push the 'cli-v2.76.1-pr-create-testing' branch? tinyfists/gh-pr-test
Working...

Creating pull request for cli-v2.76.1-pr-create-testing into main in tinyfists/gh-pr-test

? Title (required) Just a title
? Choose a template Open a blank pull request
? Body <Received>
? What's next? Add metadata
? What would you like to add? Reviewers
Working...
? Reviewers  [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]
> [ ]  amenocal (Alejandro Menocal)
  [ ]  apdarr (Alex Darr)
  [ ]  david-wiggs (David Wiggs)
  [ ]  decyjphr (Yadhav Jayaraman)
  [ ]  enyil (Enyil Valle)
  [ ]  evgenyrahman (Evgeny Rahman)
  [ ]  garnertb (Tyler Garner)
  [ ]  JaredEgolf (Jared Egolf)
  [ ]  jefeish (Jürgen Efeish)
  [ ]  jonwicksy (Jon Wicks)
  [ ]  katiem0 (Katie May)
  [ ]  kevfoste (Kevin Foster)
  [ ]  polivebranch (Payton Oliveri)
  [ ]  ssulei7 (Sully)
  [ ]  vila89 (Victoria Lam)
  [ ]  tinyfists/actions-monorepo
  [ ]  tinyfists/actions-monorepo-microservice-a
  [ ]  tinyfists/actions-monorepo-microservice-b
  [ ]  tinyfists/actions-monorepo-microservice-c
  [ ]  tinyfists/actions-monorepo-microservice-d
```

</p>
</details> 

In order to understand how to fix this, I'm recreating GHES 3.14.7 environment internally and testing `v2.76.0` against it to understand why the graceful degradation for retrieving organizational resources didn't handle this situation.  With that information, I think we will have a clear path on a fix.

https://github.com/cli/cli/blob/7d70980d8329fe30385752515bf8131314f00931/api/queries_repo.go#L24-L26

https://github.com/cli/cli/blob/7d70980d8329fe30385752515bf8131314f00931/api/queries_repo.go#L968-L979

@gcg: May the force be with you :octocat: @andyfeller: Thanks to help from @BagToad, I think I have a better understanding on #11360 circumstances and have 3 places that need to be fixed as part of this issue:

1. [`gh pr create` interactive additional metadata survey flow](https://github.com/cli/cli/blob/7d70980d8329fe30385752515bf8131314f00931/pkg/cmd/pr/shared/survey.go#L155-L191) should present teams

1. [`gh pr create --reviewer` tab completion](https://github.com/cli/cli/blob/7d70980d8329fe30385752515bf8131314f00931/pkg/cmd/pr/shared/completion.go#L14-L35) should present teams

   In `v2.72.0`, teams would show up in tab completion:

   ```shell
   andyfeller@Andys-MacBook-Pro:cli/cli ‹v2.72.0›$ bin/gh version
   gh version 2.72.0 (2025-07-29)
   https://github.com/cli/cli/releases/tag/v2.72.0
   andyfeller@Andys-MacBook-Pro:cli/cli ‹v2.72.0›$ bin/gh pr create --reviewer andrewyk
   andrewyk                  -- Andrew Kwon
   audreee                   -- Audree Steinberg
   babakks                   -- Babak K. Shandiz
   BagToad                   -- Kynan Ware
   bdehamer                  -- Brian DeHamer
   candyho                   -- Candy Ho
   cliAutomation             -- CLI Automation
   cmbrose                   -- Caleb Brose
   ejahnGithub               -- Eugene
   gedwards1                 -- Gabriel Edwards
   indigok                   -- Indigo
   jisraelsen                -- Jeremy Israelsen
   jkylekelly                -- Kyle Kelly
   joerodriguez              -- Joseph Rodriguez
   jshorty                   -- Jake Shorty
   kklopfenstein             -- Kevin Klopfenstein
   kommendorkapten           -- Fredrik Skogman
   malancas                  -- Meredith Lancaster
   misalcedo                 -- Miguel D. Salcedo
   mjimenez98                -- Miguel Jimenez
   mntlty                    -- Ariel Deitcher
   mxie                      -- Melissa Xie
   natagdunbar               -- Natalie Dunbar
   phillmv                   -- Phill MV
   Prachiti9                 -- Prachiti
   RyanHecht                 -- Ryan Hecht
   sneefyyy                  -- Jack O'Keefe
   steiza                    -- Zach Steindler
   stewartlord               -- Stewart Lord
   thomas-sickert            -- Thomas Sickert
   tingx2wang                -- Tingting Wang
   trent-j                   -- Trent Jones
   trevrosen                 -- Trevor Rosen
   VincentDondain            -- Vincent Dondain
   williammartin             -- William Martin
   yxnyxnyxnyxnyxnyxn        -- Sydney
   cli/code-reviewers        cli/deployment-reviewers  cli/tuf-root-reviewers    entitlements                                                              
   cli/codespaces            cli/package-security      cli/webhooks 
   ```

   In the latest version, teams are no longer present:

   ```shell
   andyfeller@Andys-MacBook-Pro:cli/cli ‹trunk*›$ gh version
   gh version 2.76.1 (2025-07-23)
   https://github.com/cli/cli/releases/tag/v2.76.1
   andyfeller@Andys-MacBook-Pro:cli/cli ‹trunk*›$ gh pr create --reviewer andrewyk
   andrewyk            -- Andrew Kwon
   audreee             -- Audree Steinberg
   babakks             -- Babak K. Shandiz
   BagToad             -- Kynan Ware
   bdehamer            -- Brian DeHamer
   candyho             -- Candy Ho
   cliAutomation       -- CLI Automation
   cmbrose             -- Caleb Brose
   ejahnGithub         -- Eugene
   gedwards1           -- Gabriel Edwards
   indigok             -- Indigo
   jisraelsen          -- Jeremy Israelsen
   jkylekelly          -- Kyle Kelly
   joerodriguez        -- Joseph Rodriguez
   jshorty             -- Jake Shorty
   kklopfenstein       -- Kevin Klopfenstein
   kommendorkapten     -- Fredrik Skogman
   malancas            -- Meredith Lancaster
   misalcedo           -- Miguel D. Salcedo
   mjimenez98          -- Miguel Jimenez
   mntlty              -- Ariel Deitcher
   mxie                -- Melissa Xie
   natagdunbar         -- Natalie Dunbar
   phillmv             -- Phill MV
   Prachiti9           -- Prachiti
   RyanHecht           -- Ryan Hecht
   sneefyyy            -- Jack O'Keefe
   steiza              -- Zach Steindler
   stewartlord         -- Stewart Lord
   thomas-sickert      -- Thomas Sickert
   tingx2wang          -- Tingting Wang
   trent-j             -- Trent Jones
   trevrosen           -- Trevor Rosen
   VincentDondain      -- Vincent Dondain
   williammartin       -- William Martin
   yxnyxnyxnyxnyxnyxn  -- Sydney
   ```

1. [`gh pr edit --add-reviewer` and `gh pr edit --remove-reviewer` tab completion](https://github.com/cli/cli/blob/7d70980d8329fe30385752515bf8131314f00931/pkg/cmd/pr/edit/edit.go#L201-L217) should present teams

   ```shell
   andyfeller@Andys-MacBook-Pro:cli/cli ‹v2.72.0›$ bin/gh pr edit --add-reviewer andrewyk
   andrewyk                  -- Andrew Kwon
   audreee                   -- Audree Steinberg
   babakks                   -- Babak K. Shandiz
   BagToad                   -- Kynan Ware
   bdehamer                  -- Brian DeHamer
   candyho                   -- Candy Ho
   cliAutomation             -- CLI Automation
   cmbrose                   -- Caleb Brose
   ejahnGithub               -- Eugene
   gedwards1                 -- Gabriel Edwards
   indigok                   -- Indigo
   jisraelsen                -- Jeremy Israelsen
   jkylekelly                -- Kyle Kelly
   joerodriguez              -- Joseph Rodriguez
   jshorty                   -- Jake Shorty
   kklopfenstein             -- Kevin Klopfenstein
   kommendorkapten           -- Fredrik Skogman
   malancas                  -- Meredith Lancaster
   misalcedo                 -- Miguel D. Salcedo
   mjimenez98                -- Miguel Jimenez
   mntlty                    -- Ariel Deitcher
   mxie                      -- Melissa Xie
   natagdunbar               -- Natalie Dunbar
   phillmv                   -- Phill MV
   Prachiti9                 -- Prachiti
   RyanHecht                 -- Ryan Hecht
   sneefyyy                  -- Jack O'Keefe
   steiza                    -- Zach Steindler
   stewartlord               -- Stewart Lord
   thomas-sickert            -- Thomas Sickert
   tingx2wang                -- Tingting Wang
   trent-j                   -- Trent Jones
   trevrosen                 -- Trevor Rosen
   VincentDondain            -- Vincent Dondain
   williammartin             -- William Martin
   yxnyxnyxnyxnyxnyxn        -- Sydney
   cli/code-reviewers        cli/deployment-reviewers  cli/tuf-root-reviewers    entitlements                                                              
   cli/codespaces            cli/package-security      cli/webhooks 
   ```@andyfeller: Will work with maintainers in reviewing fixes in https://github.com/cli/cli/issues/11407, thank you again for your patience 🙇 @andyfeller: @gcg : I'd appreciate your confirmation that https://github.com/cli/cli/releases/tag/v2.76.2 works as expected @gcg: > [@gcg](https://github.com/gcg) : I'd appreciate your confirmation that https://github.com/cli/cli/releases/tag/v2.76.2 works as expected

<img width="307" height="106" alt="Image" src="https://github.com/user-attachments/assets/0033e8a4-f4ae-45b1-a173-0e07e513cf22" />

works like a charm <3 

it's true what they say, you never know how much you love something unless you lose it, selecting 3 people as reviewers instead of 1 team like a peasant these past couple of days thought me this lesson. 

 

Solution patch:
diff --git a/pkg/cmd/pr/shared/completion.go b/pkg/cmd/pr/shared/completion.go
index c1296be71..9f68c0bda 100644
--- a/pkg/cmd/pr/shared/completion.go
+++ b/pkg/cmd/pr/shared/completion.go
@@ -14,7 +14,10 @@ import (
 func RequestableReviewersForCompletion(httpClient *http.Client, repo ghrepo.Interface) ([]string, error) {
 	client := api.NewClientFromHTTP(api.NewCachedHTTPClient(httpClient, time.Minute*2))
 
-	metadata, err := api.RepoMetadata(client, repo, api.RepoMetadataInput{Reviewers: true})
+	metadata, err := api.RepoMetadata(client, repo, api.RepoMetadataInput{
+		Reviewers:     true,
+		TeamReviewers: true,
+	})
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/cmd/pr/shared/survey.go b/pkg/cmd/pr/shared/survey.go
index af1fa871a..4b66bb0fa 100644
--- a/pkg/cmd/pr/shared/survey.go
+++ b/pkg/cmd/pr/shared/survey.go
@@ -181,6 +181,7 @@ func MetadataSurvey(p Prompt, io *iostreams.IOStreams, baseRepo ghrepo.Interface
 	// Retrieve and process data for survey prompts based on the extra fields selected
 	metadataInput := api.RepoMetadataInput{
 		Reviewers:      isChosen("Reviewers"),
+		TeamReviewers:  isChosen("Reviewers"),
 		Assignees:      isChosen("Assignees"),
 		ActorAssignees: isChosen("Assignees") && state.ActorAssignees,
 		Labels:         isChosen("Labels"),



Test patch:
diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go
index 469428670..9af351830 100644
--- a/pkg/cmd/pr/create/create_test.go
+++ b/pkg/cmd/pr/create/create_test.go
@@ -1655,7 +1655,7 @@ func Test_createRun(t *testing.T) {
 			expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
 		},
 		{
-			name: "if reviewer contains any team, fetch teams",
+			name: "fetch org teams non-interactively if reviewer contains any team",
 			setup: func(opts *CreateOptions, t *testing.T) func() {
 				opts.TitleProvided = true
 				opts.BodyProvided = true
@@ -1718,7 +1718,7 @@ func Test_createRun(t *testing.T) {
 			expectedErrOut: "",
 		},
 		{
-			name: "if reviewer does NOT contain any team, do NOT fetch teams",
+			name: "do not fetch org teams non-interactively if reviewer does not contain any team",
 			setup: func(opts *CreateOptions, t *testing.T) func() {
 				opts.TitleProvided = true
 				opts.BodyProvided = true
@@ -1773,6 +1773,130 @@ func Test_createRun(t *testing.T) {
 			expectedOut:    "https://github.com/OWNER/REPO/pull/12\n",
 			expectedErrOut: "",
 		},
+		{
+			name: "fetch org teams interactively if reviewer metadata selected",
+			tty:  true,
+			setup: func(opts *CreateOptions, t *testing.T) func() {
+				// In order to test additional metadata, title and body cannot be provided here.
+				opts.HeadBranch = "feature"
+				return func() {}
+			},
+			cmdStubs: func(cs *run.CommandStubber) {
+				// Stub git commits for `initDefaultTitleBody` when initializing PR state.
+				cs.Register(
+					"git -c log.ShowSignature=false log --pretty=format:%H%x00%s%x00%b%x00 --cherry origin/master...feature",
+					0,
+					"3a9b48085046d156c5acce8f3b3a0532cd706a4a\u0000first commit of pr\u0000first commit description\u0000\n",
+				)
+				cs.Register(`git rev-parse --show-toplevel`, 0, "")
+			},
+			promptStubs: func(pm *prompter.PrompterMock) {
+				firstConfirmSubmission := true
+				pm.InputFunc = func(message, defaultValue string) (string, error) {
+					switch message {
+					case "Title (required)":
+						return "TITLE", nil
+					default:
+						return "", fmt.Errorf("unexpected input prompt: %s", message)
+					}
+				}
+				pm.MarkdownEditorFunc = func(message, defaultValue string, allowEmpty bool) (string, error) {
+					switch message {
+					case "Body":
+						return "BODY", nil
+					default:
+						return "", fmt.Errorf("unexpected markdown editor prompt: %s", message)
+					}
+				}
+				pm.MultiSelectFunc = func(message string, defaults []string, options []string) ([]int, error) {
+					switch message {
+					case "What would you like to add?":
+						return prompter.IndexesFor(options, "Reviewers")
+					case "Reviewers":
+						return prompter.IndexesFor(options, "MonaLisa (Mona Display Name)", "OWNER/core")
+					default:
+						return nil, fmt.Errorf("unexpected multi-select prompt: %s", message)
+					}
+				}
+				pm.SelectFunc = func(message, defaultValue string, options []string) (int, error) {
+					switch message {
+					case "Where should we push the 'feature' branch?":
+						return 0, nil
+					case "What's next?":
+						if firstConfirmSubmission {
+							firstConfirmSubmission = false
+							return prompter.IndexFor(options, "Add metadata")
+						}
+						return prompter.IndexFor(options, "Submit")
+					default:
+						return 0, fmt.Errorf("unexpected select prompt: %s", message)
+					}
+				}
+			},
+			httpStubs: func(reg *httpmock.Registry, t *testing.T) {
+				reg.Register(
+					httpmock.GraphQL(`query UserCurrent\b`),
+					httpmock.StringResponse(`{"data": {"viewer": {"login": "OWNER"} } }`))
+				reg.Register(
+					httpmock.GraphQL(`query PullRequestTemplates\b`),
+					httpmock.StringResponse(`{ "data": { "repository": { "pullRequestTemplates": [] } } }`),
+				)
+				reg.Register(
+					httpmock.GraphQL(`query RepositoryAssignableUsers\b`),
+					httpmock.StringResponse(`
+					{ "data": { "repository": { "assignableUsers": {
+						"nodes": [
+							{ "login": "hubot", "id": "HUBOTID", "name": "" },
+							{ "login": "MonaLisa", "id": "MONAID", "name": "Mona Display Name" }
+						],
+						"pageInfo": { "hasNextPage": false }
+					} } } }
+					`))
+				reg.Register(
+					httpmock.GraphQL(`query OrganizationTeamList\b`),
+					httpmock.StringResponse(`
+					{ "data": { "organization": { "teams": {
+						"nodes": [
+							{ "slug": "core", "id": "COREID" },
+							{ "slug": "robots", "id": "ROBOTID" }
+						],
+						"pageInfo": { "hasNextPage": false }
+					} } } }
+					`))
+				reg.Register(
+					httpmock.GraphQL(`mutation PullRequestCreate\b`),
+					httpmock.GraphQLMutation(`
+						{ "data": { "createPullRequest": { "pullRequest": {
+							"id": "NEWPULLID",
+							"URL": "https://github.com/OWNER/REPO/pull/12"
+						} } } }
+						`,
+						func(inputs map[string]interface{}) {
+							assert.Equal(t, "TITLE", inputs["title"])
+							assert.Equal(t, "BODY", inputs["body"])
+							if v, ok := inputs["assigneeIds"]; ok {
+								t.Errorf("did not expect assigneeIds: %v", v)
+							}
+							if v, ok := inputs["userIds"]; ok {
+								t.Errorf("did not expect userIds: %v", v)
+							}
+						}))
+				reg.Register(
+					httpmock.GraphQL(`mutation PullRequestCreateRequestReviews\b`),
+					httpmock.GraphQLMutation(`
+					{ "data": { "requestReviews": {
+						"clientMutationId": ""
+					} } }
+				`, func(inputs map[string]interface{}) {
+						assert.Equal(t, "NEWPULLID", inputs["pullRequestId"])
+						assert.Equal(t, []interface{}{"COREID"}, inputs["teamIds"])
+						assert.Equal(t, []interface{}{"MONAID"}, inputs["userIds"])
+						assert.Equal(t, true, inputs["union"])
+					}))
+			},
+			expectedOut:    "https://github.com/OWNER/REPO/pull/12\n",
+			expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
diff --git a/pkg/cmd/pr/shared/completion_test.go b/pkg/cmd/pr/shared/completion_test.go
new file mode 100644
index 000000000..ca7c3ffa7
--- /dev/null
+++ b/pkg/cmd/pr/shared/completion_test.go
@@ -0,0 +1,120 @@
+package shared
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/cli/cli/v2/internal/ghrepo"
+	"github.com/cli/cli/v2/pkg/httpmock"
+	"github.com/stretchr/testify/require"
+)
+
+func TestRequestableReviewersForCompletion(t *testing.T) {
+	tests := []struct {
+		name              string
+		expectedReviewers []string
+		httpStubs         func(*httpmock.Registry, *testing.T)
+	}{
+		{
+			name:              "when users and teams are both available, both are listed",
+			expectedReviewers: []string{"MonaLisa\tMona Display Name", "OWNER/core", "OWNER/robots", "hubot"},
+			httpStubs: func(reg *httpmock.Registry, t *testing.T) {
+				reg.Register(
+					httpmock.GraphQL(`query UserCurrent\b`),
+					httpmock.StringResponse(`{"data": {"viewer": {"login": "OWNER"} } }`))
+				reg.Register(
+					httpmock.GraphQL(`query RepositoryAssignableUsers\b`),
+					httpmock.StringResponse(`
+						{ "data": { "repository": { "assignableUsers": {
+							"nodes": [
+								{ "login": "hubot", "id": "HUBOTID", "name": "" },
+								{ "login": "MonaLisa", "id": "MONAID", "name": "Mona Display Name" }
+							],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+				reg.Register(
+					httpmock.GraphQL(`query OrganizationTeamList\b`),
+					httpmock.StringResponse(`
+						{ "data": { "organization": { "teams": {
+							"nodes": [
+								{ "slug": "core", "id": "COREID" },
+								{ "slug": "robots", "id": "ROBOTID" }
+							],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+			},
+		},
+		{
+			name:              "when users are available but teams aren't, users are listed",
+			expectedReviewers: []string{"MonaLisa\tMona Display Name", "hubot"},
+			httpStubs: func(reg *httpmock.Registry, t *testing.T) {
+				reg.Register(
+					httpmock.GraphQL(`query UserCurrent\b`),
+					httpmock.StringResponse(`{"data": {"viewer": {"login": "OWNER"} } }`))
+				reg.Register(
+					httpmock.GraphQL(`query RepositoryAssignableUsers\b`),
+					httpmock.StringResponse(`
+						{ "data": { "repository": { "assignableUsers": {
+							"nodes": [
+								{ "login": "hubot", "id": "HUBOTID", "name": "" },
+								{ "login": "MonaLisa", "id": "MONAID", "name": "Mona Display Name" }
+							],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+				reg.Register(
+					httpmock.GraphQL(`query OrganizationTeamList\b`),
+					httpmock.StringResponse(`
+						{ "data": { "organization": { "teams": {
+							"nodes": [],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+			},
+		},
+		{
+			name:              "when teams are available but users aren't, teams are listed",
+			expectedReviewers: []string{"OWNER/core", "OWNER/robots"},
+			httpStubs: func(reg *httpmock.Registry, t *testing.T) {
+				reg.Register(
+					httpmock.GraphQL(`query UserCurrent\b`),
+					httpmock.StringResponse(`{"data": {"viewer": {"login": "OWNER"} } }`))
+				reg.Register(
+					httpmock.GraphQL(`query RepositoryAssignableUsers\b`),
+					httpmock.StringResponse(`
+						{ "data": { "repository": { "assignableUsers": {
+							"nodes": [],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+				reg.Register(
+					httpmock.GraphQL(`query OrganizationTeamList\b`),
+					httpmock.StringResponse(`
+						{ "data": { "organization": { "teams": {
+							"nodes": [
+								{ "slug": "core", "id": "COREID" },
+								{ "slug": "robots", "id": "ROBOTID" }
+							],
+							"pageInfo": { "hasNextPage": false }
+						} } } }
+					`))
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			reg := &httpmock.Registry{}
+			defer reg.Verify(t)
+			if tt.httpStubs != nil {
+				tt.httpStubs(reg, t)
+			}
+
+			reviewers, err := RequestableReviewersForCompletion(&http.Client{Transport: reg}, ghrepo.New("OWNER", "REPO"))
+			require.NoError(t, err)
+			require.Equal(t, tt.expectedReviewers, reviewers)
+		})
+	}
+}