Create a GitHub Label with gh label create
A label with no description and a random colour is easy to make and hard to trust later, so gh label create is worth doing properly the first time. You will finish with a repeatable command for naming, colouring and describing a label, plus a way to check it landed.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need GitHub CLI, an authenticated account that can manage labels in the target repository, and the repository's OWNER/REPO name. No root access needed. The examples use GitHub CLI 2.87.3, installed here as the gh package command; GitHub CLI talks to the remote service, so authentication and repository permissions matter more than local ones.
1. Check the installed command
Start with read-only checks. They confirm which binary is on your path and show the option syntax for the version actually installed:
$ gh --version
gh version 2.87.3 (2026-02-23)
$ gh label create --help
Create a new label on GitHub, or update an existing one with \`--force\`.
The shape is gh label create NAME [flags]. The local manual documents --description, the short -c colour option, --force, and the inherited --repo flag; the full help text has more surrounding detail, but those are the options this guide uses.
Checkpoint
If gh --version fails, stop and fix the installation or your PATH first. Do not substitute a similarly named script without checking it.
2. Confirm the repository and authentication
Name the repository in the command rather than trusting the current directory, especially useful outside a checkout or with several repositories open:
$ REPO='OWNER/REPO'
$ gh auth status
$ gh label list --repo "$REPO" --limit 30
- Replace the placeholder.
OWNER/REPObecomes something real, such asacme/widgets, before anything that changes state. - Let the list command double as a sanity check. It proves the repository is reachable and shows existing label names.
- Fix authentication first. If it fails, sort that out with your normal GitHub CLI login process before continuing.
The inherited --repo flag also accepts [HOST/]OWNER/REPO for a GitHub Enterprise host; use the host explicitly when the repository is not on github.com. Elevated privileges fix none of a wrong host, missing permission, or expired token.
3. Pick a name, description and colour
A name is required. Description and colour are optional, but setting both makes the label easier to recognise later and less dependent on GitHub's defaults. Colour must be six hexadecimal characters, no leading #, for example E99695:
$ LABEL='needs-reproduction'
$ DESCRIPTION='The issue needs a minimal reproducible example'
$ COLOUR='E99695'
Names and descriptions are repository metadata, so keep secrets, email addresses and incident details out of them. Quote the values as shown: quoting protects spaces and shell metacharacters from your shell, it does not validate the content for GitHub.
Tip
A missing colour is not a stable default. The manual says GitHub CLI picks a random one when you leave it out. If appearance matters, set the six-character value yourself; a malformed value is likely to be rejected outright, so fix it rather than guessing again.
4. Create the label
Run this ordinary user command, no sudo, only after checking the repository and values above:
$ gh label create "$LABEL" \
--description "$DESCRIPTION" \
-c "$COLOUR" \
--repo "$REPO"
Its network request can fail on authentication, permissions, a misspelled repository, or plain connectivity, so read the error before rerunning it.
Checkpoint
Verify the label by searching its name and asking for JSON fields that leave nothing ambiguous:
$ gh label list --repo "$REPO" --search "$LABEL" --json name,description,color
[{"color":"E99695","description":"The issue needs a minimal reproducible example","name":"needs-reproduction"}]
The JSON above is an example of the fields to inspect, not a promise about whitespace or array formatting. Confirm the name, description and colour; if the search returns several similar labels, match on the exact name in the returned records.
5. Handle a name that already exists
Warning
Do not add --force by reflex. It updates the existing label's colour and description, a state change that can overwrite metadata another maintainer chose deliberately:
$ gh label create "$LABEL" \
--description "$DESCRIPTION" \
-c "$COLOUR" \
--force \
--repo "$REPO"
Use it only after comparing the current record with the values you intend to apply. There is no separate confirmation prompt in the documented command shape, so treat --force as an explicit overwrite instruction, not a harmless retry switch.
Recovery
If you know the previous description and colour, run the same command again with the original values and --force. If you do not, stop and ask a repository maintainer or check the label's history through your normal GitHub workflow. A duplicate-looking label with a different spelling is usually a worse outcome than fixing the one you have.
6. Diagnose the common failures
- Missing name. That is a local command error, nothing to debug remotely.
- Repository error. Usually
REPOis wrong, the host is wrong, or your account cannot manage labels there. Recheck without changing anything:
$ printf 'repository: %s\n' "$REPO"
$ gh label list --repo "$REPO" --limit 1
$ gh auth status
- Colour rejected. Count the hex characters and strip any leading
#. The requirement is exactly six. - Label seems missing after success. Search with the exact name and the same
--repovalue used to create it; the current checkout's repository is not a substitute for naming the target explicitly.
Do not rerun the create command repeatedly while chasing a network timeout. List the labels first, then decide whether a retry is safe. With --force a retry can also reapply an update, so keep the intended values written down to compare against the current result.
Done means
- Command and options checked.
gh --versionandgh label create --helpmatch the installed version. - Repository named explicitly. Checked with
--repo, never assumed from the current directory. - Name, description and colour reviewed. Six-character hex colour confirmed before the change.
- Label verified, not just created. Confirmed with
gh label list, no elevated privileges used. - Force used deliberately, if at all. Only to intentionally update an existing label.
- Reversal path known. Original metadata or a maintainer contact identified in case an overwrite needs undoing.