Move a GitHub Issue with gh issue transfer
Get the destination wrong and gh issue transfer will cheerfully send your issue to a repository you never meant to touch. This guide checks both repos and the issue itself before you move anything. Allow about ten minutes.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need gh installed, an authenticated account, access to both repositories, and permission to transfer the issue. The examples use gh 2.87.3 from the gh package; the local manual is dated March 2026, so check your own version first, since behaviour and permissions can change between releases.
1. Check gh and confirm your account
Start read-only. Neither of these needs elevated privileges:
$ command -v gh
/home/linuxbrew/.linuxbrew/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)
Then check who you are logged in as. Do not paste a token into a command, a shell history file or this guide:
$ gh auth status
github.com
Logged in to github.com account YOUR_ACCOUNT
...
Your account name and the exact wording will differ. Not logged in? Use your normal organisational authentication process. sudo will not help here: elevated local privileges do not grant GitHub repository access.
Checkpoint
gh auth status names the account you intend to use, and that account can reach both repositories.
2. Read the command's shape
The command takes an issue number or a full issue URL, followed by the destination repository:
$ gh issue transfer {<number> | <url>} <destination-repo> [flags]
The destination is written as OWNER/REPO. The inherited -R or --repo flag picks the source repository, in [HOST/]OWNER/REPO form; it does not touch the destination. Mixing those two up is the easiest way to send an issue to the wrong place, so write both repository names down before running anything.
Check the local help whenever you are unsure of the syntax:
$ gh issue transfer --help
Transfer issue to another repository
USAGE
gh issue transfer {<number> | <url>} <destination-repo> [flags]
INHERITED FLAGS
--help Show help for command
-R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format
3. Look at the issue before you touch it
Use gh issue view to confirm the number, title and source repository. Replace every uppercase placeholder with a real value:
$ SOURCE_REPO='YOUR_ORG/source-repo'
$ ISSUE_NUMBER='123'
$ DESTINATION_REPO='YOUR_ORG/destination-repo'
$ gh issue view "$ISSUE_NUMBER" --repo "$SOURCE_REPO"
Issue #123 in YOUR_ORG/source-repo
Example title
...
The title on screen is your checkpoint. Stop if the number, repository or title is not exactly the one you meant to move. A shell variable is only a convenience: it does not validate a repository name or protect you from the wrong account.
Prefer an unambiguous URL? The transfer command accepts one too:
$ gh issue transfer 'https://github.com/YOUR_ORG/source-repo/issues/123' "$DESTINATION_REPO"
Do not run that line yet if you are still checking the target. It changes GitHub state.
4. Know there is no undo
Warning
Transferring an issue is a repository-side change, not a local copy. Anyone using the issue URL, automation or a project workflow is affected. The installed manual documents no dry-run, no confirmation flag and no undo subcommand.
- Write down the details first. Source repo, issue number, destination repo and the current title.
- Check repository policy. Labels, milestones, projects, links and automation can all depend on the issue staying where it is.
- Coordinate if it matters. If the issue is part of a live incident or release, tell the people watching it before you move it.
Recovery
There is no local rollback command. If the transfer was wrong, use GitHub's own issue-management workflow or ask a repository administrator. Do not guess at a reversal by running the command again: its destination argument always means where the issue is going, never where it came from.
5. Run the transfer
After the checkpoint, run one of these ordinary, unprivileged commands. Use the number form when --repo already selects the source:
$ gh issue transfer "$ISSUE_NUMBER" "$DESTINATION_REPO" --repo "$SOURCE_REPO"
Transferred issue ...
The final message is server- and version-dependent, so treat the exit status as your first signal, not the last word. A zero exit status only means the CLI completed the request. On an error, keep the output and do not blindly retry until you know whether the issue actually moved.
The URL form makes the source explicit, which helps when you are juggling several repositories:
$ gh issue transfer \
'https://github.com/YOUR_ORG/source-repo/issues/123' \
'YOUR_ORG/destination-repo'
Do not mix an issue URL from one repository with a different source picked by --repo. Pick one clear source reference per command.
6. Confirm it landed
Use the destination issue number or URL GitHub hands back, if it gives you one:
$ gh issue view NEW_ISSUE_NUMBER --repo "$DESTINATION_REPO"
Issue #NEW_ISSUE_NUMBER in YOUR_ORG/destination-repo
Example title
...
If the number carried over, try "$ISSUE_NUMBER" at the destination. If it did not, use whatever number or URL the response gave you: do not assume the old number still applies. GitHub's web interface works too, for a quick look at the title and discussion.
On a failure, check both repositories before retrying:
$ gh issue view "$ISSUE_NUMBER" --repo "$SOURCE_REPO"
$ gh issue list --repo "$DESTINATION_REPO" --search 'Example title'
Search terms can match more than one issue, so confirm the repository and title, not just the first hit. If access, org policy or issue state is blocking the move, fix that or ask an administrator; do not escalate local privileges to work around it.
Done means
- Version and account checked.
gh --versionidentified the CLI, andgh auth statusconfirmed the account. - Source confirmed. Issue number, title and repository matched your change record.
- Destination written correctly. The intended
OWNER/REPO, kept separate from the source picked by--repo. - No undo, and you knew it. The transfer changes GitHub state with no documented local undo.
- Destination checked. By its resulting number, URL or title, not by assumption.
- Failures held, not retried blind. Output kept until the issue's actual location was clear.