Edit a GitHub Project Safely with gh project edit

Run gh project edit and you get dead silence back, even on success. This guide covers changing a GitHub Project's title, description, README or visibility from a shell with GitHub CLI 2.87.3, checking the result properly instead of guessing from an empty terminal, and keeping every change reversible.

1. Confirm the installed command

Check the binary and version before copying any example here. This step is read-only:

$ command -v gh
/usr/bin/gh
$ gh --version
gh version 2.87.3 (2026-02-23)

Then read the installed command's own option list:

$ gh project edit --help
Edit a project

USAGE
  gh project edit [<number>] [flags]

Checkpoint: the command is gh project edit, the project number is optional in the synopsis, and the owner is supplied separately with --owner. The installed manual has no list operation here, so do not guess a project number.

2. Check authentication and pick the target

Confirm the account has a working GitHub session before attempting an edit:

$ gh auth status
github.com
  Logged in to github.com account YOUR_ACCOUNT
  ...

The account name and details vary by machine. If the command reports you are not logged in, stop and authenticate through your normal GitHub CLI process. Do not paste a token into shell history or an article example.

$ gh project edit 12 --owner @me --title "Release planning"

Replace 12 and the title with real values. Keeping the owner explicit in scripts makes the destination easier to audit and stops the command relying on whoever happens to be logged in.

3. Change one text field at a time

Start with one field per command so the change is easy to review and undo. The title option is --title, with -t as its short form:

$ gh project edit 12 --owner @me --title "Release planning"

A successful edit normally produces no useful standard output. Do not mistake an empty terminal response for a displayed project record: treat the exit status as the first check, then inspect the project in GitHub or with a separate read command.

To replace the description, use --description or -d:

$ gh project edit 12 --owner @me --description "Tasks and decisions for the 2026 release."

Both options replace the existing value outright. If you need to keep the current wording, copy it first from the project interface or an approved API query, then send the complete replacement. Double quotes allow shell expansion; single quotes keep the text literal. Pick whichever matches your content.

4. Replace the project README

The --readme option replaces the project's README content wholesale. Keep the new content in a file first so you can review it before sending it:

$ cat > /tmp/project-readme.md <<'EOF'
# Release planning

Track release scope, owners and decisions here.
EOF
$ gh project edit 12 --owner @me --readme "$(cat /tmp/project-readme.md)"

The temporary file sits outside the project and is not uploaded by itself, so read it before running the edit. The command substitution passes its contents as one argument, embedded newlines and all. Keep credentials, private incident details or anything copied from an untrusted document out of a public project README.

Recovery: there is no automatic undo flag. Keep the previous README in a trusted local file before replacing it, then run gh project edit ... --readme "$(cat previous-readme.md)" to restore it if needed.

5. Treat visibility as a high-risk change

--visibility accepts PUBLIC or PRIVATE. Changing to PUBLIC can expose project content to people who could not previously see it, so review the title, description, README, linked issues and access expectations first:

$ gh project edit 12 --owner @me --visibility PRIVATE

Use the uppercase values exactly as documented. A successful return does not mean every linked resource is now private too: GitHub's own permissions on those resources still apply separately. If you pick the wrong value by accident, run the command again with the intended one as soon as you have checked the target:

$ gh project edit 12 --owner @me --visibility PUBLIC

Warning: that is a state change, not a dry run. Plan a recovery path before making it, and never use it as a casual visibility test.

6. Ask for structured output when you need a record

The command accepts --format json, plus --jq and --template for filtering or formatting. An edit may still produce little or no output, so reach for these only when your installed version actually returns data for the operation you ran:

$ gh project edit 12 --owner @me --title "Release planning" --format json

For a small machine-readable result, the documented filter syntax looks like this:

$ gh project edit 12 --owner @me --description "Tasks for the release" --format json --jq '.title'

An empty result or a filter that returns nothing does not necessarily mean the edit failed. Check the exit status, then verify the project through GitHub's project view or a separate read operation, rather than building a script around output you have not actually observed.

7. Diagnose the common failures

A missing number, wrong owner or insufficient permission can all block the edit. Check the target spelling before touching authentication or adding unrelated flags:

$ gh project edit 12 --owner example-org --title "Release planning"
HTTP 404: Not Found (https://api.github.com/...)

The exact error depends on the account and project. A 404 can mean the project does not exist, or that the account simply cannot see it. An authentication error means the session needs attention. Neither is fixed by sudo.

Do not add --readme, --visibility or other flags while you are still troubleshooting a title edit: every supplied field is another remote change. Make one correction at a time, verify it, and print a safe description of any shell variable involved rather than assuming its contents:

$ project_number='12'
$ owner='example-org'
$ printf 'editing project %s owned by %s\n' "$project_number" "$owner"
editing project 12 owned by example-org
$ gh project edit "$project_number" --owner "$owner" --title 'Release planning'

Done means