Skip to main content

is-it-claimed

Check whether a GitHub issue is already being worked on — before you write the patch.

$ is-it-claimed owner/repo#606
CLAIMED (high confidence)
  owner/repo#606  serve backend hand-rolls its own prompt

  ! @contributor has an OPEN PR for this — fix: apply the model's chat template
    https://github.com/owner/repo/pull/607

No dependencies. Python 3.9+.

Why

An issue with no assignee and no comments looks free. It often isn't.

This tool exists because of a specific afternoon: an issue was filed at 16:27, a pull request fixing it was opened 50 seconds later, and a second contributor — who had checked the issue for a claim and found none — started the same work at 16:52 and finished it. Two people wrote the same patch, and a maintainer had to spend their time choosing between them.

Nothing was done wrong. The claim simply wasn't anywhere the second contributor looked. GitHub records a referencing PR in the issue's timeline, not in its comments, so gh issue view does not show it and neither does the web page's comment thread.

is-it-claimed looks in all four places a claim actually hides.

Install

pip install is-it-claimed
# or, without installing:
uvx is-it-claimed owner/repo#123

Use

is-it-claimed owner/repo#123
is-it-claimed https://github.com/owner/repo/issues/123
is-it-claimed owner/repo#123 --forks     # also scan forks for a matching branch
is-it-claimed owner/repo#123 --json      # machine-readable

Exit codes make it scriptable — 0 available, 1 claimed, 2 error:

is-it-claimed "$ISSUE" || { echo "someone is already on it"; exit 1; }

The question is rarely "is this one issue free?". It is "of these forty, which can I take?" — so point it at a search instead:

$ is-it-claimed --search 'label:"good first issue" no:assignee language:python' \
                --available-only
40 checked, 6 available, 34 claimed

  AVAILABLE owner/repo#4421                  Improve error message on bad config
  AVAILABLE other/project#5502               Docs: nested blueprint example
  ...

Without --available-only it lists everything and says why each one is taken:

$ is-it-claimed --search 'repo:owner/repo label:"good first issue"'
4 checked, 1 available, 3 claimed

  AVAILABLE owner/repo#273    Cover three uncovered branches
  CLAIMED   owner/repo#276    Add ready-made recipe
            @contributor has an OPEN PR for this — feat: add recipes

Several issues can also be given directly:

is-it-claimed owner/repo#1 owner/repo#2 other/repo#3

Sweeps run concurrently (--workers, default 6). In a sweep the exit code answers "is there anything here for me?" — 0 if at least one issue is available, 1 if none are.

It will not start a sweep it cannot finish. Each issue costs about three API calls, so the remaining hourly quota is checked first; if it is short, the sweep is trimmed and says so rather than emitting forty identical rate-limit errors:

  ! only 40 requests left this hour; checked the first 8 of 20

What it checks

Signal Weight Why it matters
Open/merged PR referencing the issue 4 Near-proof. The work exists, not just the intent. This is the one gh issue view doesn't show you.
Assignee 3 The explicit signal — and the least used.
A comment claiming it 2 "I'll take this", "working on it", …
A fork with a branch naming the issue 1 Work started, no PR yet. Opt-in via --forks.
Closed PR referencing the issue 0 Not a claim — nobody is working on it now. Shown as context, never hidden.

Weights add up into a confidence level, because these signals are not equal. A fork branch alone is a hint; someone may have abandoned it months ago. An open PR is as close to certain as this gets.

Claim phrases are matched conservatively. "Can I work on this?" is a question, not a claim, and treating it as one would tell you an issue is taken when it is merely being discussed.

A claim goes stale. An open PR nobody has touched in 90 days, or a comment saying "I'll take this" written eight months ago with no follow-up, is not a live claim — the work was intended, then abandoned. Both are downgraded to a weak signal and labelled with their age, so you can see it and judge. Tune the threshold with --stale-days N.

CLAIMED (low confidence)
  ! @contributor has an open but STALE PR (240 days idle) — feat: add the thing

A draft is weaker than a ready PR. A draft says "not ready for review", so it scores below one its author has put up for merging.

A closed PR is not a claim. Closed without merging means nobody is working on it now, so the issue is available — and scoring it as taken would hide free work behind --available-only. But it is not nothing either: the attempt may have been abandoned, or rejected by the maintainer, and those look identical from outside. So it carries no weight and is always shown, under --available-only too:

AVAILABLE owner/repo#4813   Add a data-source connector
          - @contributor opened a PR for this, closed unmerged 27 days ago

Read it before repeating it.

A mention is not a fix. GitHub creates a cross-reference whenever a pull request mentions an issue number — including in passing. If such a PR merged and the issue is still open, it plainly did not resolve it, so it is reported as context rather than counted as a claim. Without that distinction the tool marks genuinely free issues as taken, which is the expensive direction to be wrong in.

Authentication

Optional, but recommended — unauthenticated GitHub allows 60 requests/hour, and --forks can spend that on one check.

The token is picked up from GITHUB_TOKEN, GH_TOKEN, ~/.config/gh/hosts.yml, or gh auth token — that last one matters on macOS, where gh keeps the token in the keychain and the config file has none. If you have run gh auth login there is nothing to do.

Partial results

If one check fails — rate limit, a deleted fork — the others still run and the failure is reported:

AVAILABLE
  no claim found in: assignee, comments
  ? could not check fork branches: refused (403)

A definitive answer already found in the timeline is not thrown away because a later, weaker check failed.

Limits

  • A claim made somewhere else entirely — Discord, a mailing list, a maintainer's head — is invisible here. AVAILABLE means "no public signal", not "nobody is working on it".
  • --forks scans the 30 most recently pushed forks by default. A very popular repository has more.
  • Claim-phrase matching is English-only.

Licence

MIT

Metadata

Release files for is-it-claimed 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for is-it-claimed 0.4.0
File Size Uploaded
is_it_claimed-0.4.0.tar.gz 30.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for is-it-claimed 0.4.0
File Interpreter ABI Platform
is_it_claimed-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.0 kB

Release files / is_it_claimed-0.4.0.tar.gz

Download URL is_it_claimed-0.4.0.tar.gz
Size 30.9 kB
Tags Source
SHA-256 checksum
How to use checksums
85b74da254e910d917bba5d2f3c651f8f5ce647fcfa59f87400e9a0b0712c8c2
BLAKE2b-256 checksum
How to use checksums
4c8c22ed3febb74a51812494d3df66be62c99823d791aecfb66ddb5e9957becd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / is_it_claimed-0.4.0-py3-none-any.whl

Download URL is_it_claimed-0.4.0-py3-none-any.whl
Size 17.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c1aeda36f1b97c80ae0aa7ce3f86ceeb0a040a6301c65833e341e6e6f16469d
BLAKE2b-256 checksum
How to use checksums
fc9899749b5579a16b2c147b6fb2260ec404342e043695314bfc715504fdd484
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page