Closing the wrong issue with gh issue close takes one careless paste, so this guide checks the target twice first. Allow about five minutes for a routine close, or longer if you need to confirm the repository and issue first. This guide uses GitHub CLI 2.87.3, installed as the gh command on the machine used for these examples.
You need the GitHub CLI, an authenticated account with permission to change issues, and either a local checkout of the target repository or an explicit repository name. Closing an issue changes shared project state, so read it and confirm its number before the final command. No step needs sudo.
Start with a read-only check. This catches a missing command and shows the version whose behaviour you are about to rely on:
$ command -v gh
/usr/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)
The installed manual defines the command as gh issue close {<number> | <url>} [flags]. The only close-specific options are --comment (or -c) and --reason (or -r). The accepted reasons are completed and not planned.
Checkpoint: a different release reported by gh --version means run gh issue close --help and check the local syntax before copying the examples below. A distribution package version and the executable version are not always the same thing.
Inside the intended Git checkout, inspect the issue before changing it. Replace 42 with the issue number you have reviewed:
$ gh issue view 42
Issue details appear here, including its title and current state.
The output is repository-specific, so the title and state are the useful checks, not a fixed line of text. Current directory is not the checkout, or points at the wrong remote: specify the repository with --repo:
$ gh issue view 42 --repo OWNER/REPOSITORY
You can also pass the issue URL directly to gh issue close. That is useful across several repositories, but inspect it carefully before pressing enter. A shell variable cuts repeated typing while keeping the target visible:
$ ISSUE_URL='https://github.com/OWNER/REPOSITORY/issues/42'
$ printf '%s\n' "$ISSUE_URL"
https://github.com/OWNER/REPOSITORY/issues/42
An unauthenticated account makes the close request fail rather than silently change anything. Check authentication with gh auth status. If that fails, authenticate through your normal approved GitHub process; do not paste a token into a command, script or issue comment.
Use completed when the requested work is done, and not planned when the project will not pursue it. The reason is part of the issue's shared record, so pick it deliberately rather than treating it as cosmetic.
A comment is optional. Add one when future readers need a concise explanation, such as a link to the replacement issue or the decision that ended the work:
$ gh issue close 42 \
--reason completed \
--comment 'Implemented in pull request #57.'
Keep the comment in single quotes when it holds ordinary punctuation. An apostrophe inside it means switch to double quotes, or build the text through a carefully reviewed shell variable instead. Do not include passwords, access tokens, private customer data or internal incident details in a public issue comment.
Checkpoint: before running the state-changing command, confirm all three values: the repository, the issue number, and the chosen reason. Any of them uncertain: stop and go back to step 2.
Target checked, run the smallest suitable command. This is the irreversible part of the workflow from other contributors' point of view, so do not put an unreviewed issue number in a script or a broad loop:
$ gh issue close 42 --reason not planned --repo OWNER/REPOSITORY
Use either a number or a URL, not both. Exit status 0 means the command completed successfully; non-zero means it failed. A successful exit status means the CLI completed the request, but it is still worth checking the resulting state, especially in automation.
Do not add sudo. GitHub permissions and CLI authentication control this operation; local root privileges grant no permission in the repository. Authentication, permission, network or repository error: preserve the message and fix that specific problem before retrying. A command that might have already succeeded just before a connection dropped is not one to repeat blindly.
Ask GitHub for the issue after the command returns:
$ gh issue view 42 --repo OWNER/REPOSITORY --json number,title,state
{
"number": 42,
"state": "CLOSED",
"title": "The issue title appears here"
}
Your own title will differ. The values that matter are the expected number and "state": "CLOSED". State not closed: treat the operation as incomplete and check the command's error output. Title not the one you reviewed: stop, you may have the wrong issue number.
For a script, make the verification explicit and fail if it does not produce the expected state:
$ state=$(gh issue view 42 --repo OWNER/REPOSITORY --json state --jq .state)
$ test "$state" = CLOSED
$ printf 'verified state: %s\n' "$state"
verified state: CLOSED
The test command prints nothing on success, so the final line is the visible checkpoint. Keep the repository and number fixed in both commands: changing either one mid-debug turns a verification into a check of a different issue.
Closing an issue does not delete its discussion. Closed the wrong one and you have permission to correct it:
$ gh issue reopen 42 --repo OWNER/REPOSITORY
Verify the repair the same way:
$ gh issue view 42 --repo OWNER/REPOSITORY --json state --jq .state
OPEN
Reopening changes shared state too. Tell the project maintainers what happened, and do not use reopening to quietly cover up an accidental close. A misleading comment added along with the close is a separate matter: check the repository's permissions and moderation process before attempting any edit or deletion.
gh version and local close syntax matched what you expected.completed or not planned, not a default.CLOSED.gh issue reopen and verified.