EUComply

GitHub phantom ("ghost") notifications that won't go away

Updated August 2026 · 5 min read

The badge says 1 unread. You open the notification, read the thread, go back — and it's still there. Or you mark everything as read, the count hits zero, and an hour later the same item is unread again. This is one of the most-reported GitHub annoyances of the last few years, and it has a handful of specific, fixable causes.

Why it happens at all

GitHub's notification is a pointer to a thread, not to a message. A thread stays "unread" until GitHub considers every reason you were subscribed resolved. That means a thread can be unread even when nothing new is visible to you — for example when the last activity happened in a part of the conversation you can't see, or when your subscription outlived the thing you cared about. Clients that cache this state (including browser tabs left open for days) make it look even more haunted than it is.

Fix 1: Mark as done, not just as read

Since 2023 GitHub has two separate concepts in the inbox:

A read-but-not-done thread keeps living in your inbox. Open github.com/notifications, hover the stubborn item and press "Done" (or select several and use the Done button). Done items stop counting and stop resurfacing. If your badge counts "inbox items" rather than strictly-unread items, this alone explains most phantoms.

Fix 2: Unsubscribe from the thread instead of fighting it

If "Done" isn't available (some third-party clients only expose read/unread), unsubscribe directly: open the notification, click Subscribe/Unsubscribe in the right sidebar on the thread, and choose Unsubscribe. You'll stop receiving updates for that thread unless you're @mentioned again. For issues in repos you don't contribute to, this is the cleanest escape.

Fix 3: Clear the stale state via the API

When the web UI insists a thread is unread no matter what you click, the thread's server-side state may be genuinely stuck. The notifications API can reset what the UI sometimes can't:

  1. Create a personal access token with the notifications scope (Settings → Developer settings → Personal access tokens).
  2. Mark the phantom thread as read directly:
curl -X PATCH \
  -H "Authorization: Bearer ghp_YOURTOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/notifications/threads/THREAD_ID

You can list thread IDs with GET https://api.github.com/notifications and find the offender by its title. After the PATCH, refresh github.com — the ghost is normally gone. Desktop clients that poll this same API pick up the cleared state within a minute or two.

Fix 4: Rule out the boring causes first

See the real unread count — always in sync

DevNotify polls GitHub's notifications API directly, so its menu bar count reflects actual server state — no stale tabs, no frozen caches. When something won't clear in the browser, DevNotify's own mark-as-done clears it for real. Free to try, $19 for a lifetime license.

Download DevNotify for macOS Buy license — $19

Still stuck?

If a specific thread survives all four fixes, check whether the repo has been archived or made private — threads in repos you've lost access to can linger as permanently unreadable entries, and only GitHub support can purge those. For everyone else, Fix 1 (Done) plus Fix 3 (API) resolves the vast majority of cases reported over the last three years.