How to Stop Duplicate Jira Tickets from Multiple Integrations
You can't stop it at the integration level, because none of the three integrations know the other two exist. Sentry's alert rules can create a Jira issue automatically when an alert fires, GitHub's own Jira app only links commits and pull requests to issues that already exist rather than creating new ones, and a Slack-reported bug usually becomes a ticket because a person typed it in by hand. Three different paths, three different tickets, and nothing connecting them but the fact that they describe the same failure.
The fix that actually works catches the duplicate before it's filed, not after. A five-second search habit at ticket-creation time, backed by Jira's built-in duplicate-linking, means the ones that slip through still collapse into one canonical ticket. Below a few dozen cross-integration reports a month, that combination holds up fine. Above it, you need something reading all three sources before any of them reach Jira, which is the part this guide gets to at the end.
Why the three paths don't recognize each other
It helps to be precise about which of the three actually creates tickets on its own, because only one of them does.
Sentry's Jira integration has two modes: a manual "create or link Jira issues" action from an issue's Linked Issues panel, and an alert-rule action that files a ticket automatically the moment an alert condition is met. Sentry's own docs describe the automatic path plainly: "A Jira issue will be created automatically when the alert has been triggered." What the docs don't cover is what happens if that same underlying error re-triggers a second alert after the first ticket already exists, or if a re-grouped issue fires a fresh alert for the same underlying bug. There's no documented check against an existing linked ticket. The action just runs.
GitHub is the one that surprises people, because it looks like it should auto-file the same way. It doesn't. Atlassian's own GitHub for Jira documentation is explicit that the app connects a GitHub org to Jira so your team can "link their development activity to Jira work items" — branches, commits, pull requests — against issues that already exist. It has no feature that opens a new Jira ticket when someone files a GitHub issue. When a GitHub-sourced duplicate shows up in Jira, it's almost always because a person read the GitHub issue and manually created a ticket from it, not because an integration did it automatically.
Slack duplicates follow the same manual pattern from the other direction. Someone sees a customer or teammate describe a bug in a shared channel, and rather than search first, opens a new Jira ticket to make sure it's tracked. It's a reasonable instinct, but it has the same blind spot as the other two, because nobody involved checked whether a ticket already existed.
Together, that's one automatic path with no dedupe check, and two manual paths where the person filing has no visibility into what Sentry or the other channel already created. None of the three is wrong on its own. The gap is between them.
The search habit that catches most of it before it's filed
The cheapest fix costs nothing to build. Before creating any ticket sourced from an alert, a GitHub issue, or a Slack message, search Jira first. A saved JQL filter scoped to the relevant project (project = PLAT AND text ~ "webhook retry", or whatever term describes the failure) takes less time to run than filling out the create-issue form, and it's the single habit that prevents the most duplicates from ever existing.
This only works if it's a habit everyone filing tickets actually has, which is the same limitation every manual dedupe step runs into. It survives a five-person team. It gets skipped under load.
When the search habit misses one, link it and move on
Jira has a built-in link type for exactly this case. Atlassian's documentation on linking issues lists "duplicates" and "is duplicated by" among the default link types, so closing a duplicate doesn't have to mean losing the connection to the original. In practice that means closing the newer ticket, linking it as a duplicate of the older one, and dropping a comment on the canonical ticket noting the second source ("also reported via Sentry alert, same webhook retry failure"). Anyone who lands on the closed ticket later, from a Slack thread or a customer email, can follow the link straight to the ticket that's actually being worked.
Do this every time a duplicate turns up, not only when someone happens to notice. The value of the link is that severity and reporter count accumulate on one ticket instead of scattering across three, which is exactly the information a prioritization call needs later.
When three tickets landed on Kwame's board in the same sprint
Kwame Asare runs the on-call rotation for the platform team at Basalt Systems, which builds subscription billing tooling for mid-size e-commerce brands. During a Tuesday sprint-planning session, he noticed three open tickets that all touched the checkout-sync service:
BAS-4471, auto-filed by a Sentry alert rule: "Checkout webhook retries exceeding threshold on
sync-checkoutworker."BAS-4483, filed by a support teammate off a Slack message: "Customer (Northrail Goods) says invoice totals aren't updating after checkout."
BAS-4498, filed by a Basalt SDK engineer after a partner developer flagged it in a GitHub issue on Basalt's public SDK repo: "SDK reports webhook retries failing silently under load."
Kwame read all three descriptions back to back and recognized the same failure described three ways. The webhook retry logic was swallowing errors instead of surfacing them, which meant invoice totals went stale and the SDK's retry counter looked fine when it wasn't. Nobody who filed BAS-4483 or BAS-4498 had seen BAS-4471, because one came from an automated alert, one from a Slack thread a support rep read on their own, and one from a GitHub issue an SDK engineer happened to notice.
He closed BAS-4483 and BAS-4498 as duplicates of BAS-4471, added a comment listing all three sources and the two affected customers, and left BAS-4471 as the working ticket with everything attached. "Three filings, one bug, and it took me reading all three descriptions in the same sitting to catch it," he told his team lead. "If planning had landed on a Thursday instead of a Tuesday, I might have worked BAS-4471 and BAS-4498 in parallel without ever noticing they were the same fix."
Where the manual habit stops holding up
The search-first-then-link approach works as long as one person can plausibly read every new ticket closely enough to recognize the same failure worded three different ways. That assumption breaks down predictably as volume grows. Search terms miss reworded descriptions the same way Jira's own similar-requests matching misses them, nobody's reading every ticket closely enough to catch a phrasing like "invoice totals stale" against "webhook retries exceeding threshold," and the moment a fourth source gets added (a support email, a customer call transcript), there's no ticket in Jira to search against at all, because nothing filed one yet.
This is the point where teams stop trying to catch duplicates after they land in Jira and start deduping before anything reaches it. That's the layer Modem works at. It correlates Sentry alerts, GitHub issues, and Slack messages into a single topic even when the wording and channel are completely different, so Kwame's three reports would show up as one topic with three sources and two customers attached, well before anyone sat down to compare three separate Jira descriptions by hand. Filing or linking the actual Jira ticket from there is something an agent does when a person asks it to, the same approval-gated pattern behind every Modem action: nothing gets created, resolved, or reassigned without someone asking for it and signing off. Details on the Jira side of that connection are on the Jira integration page. We have an obvious stake in that comparison, since we build Modem; below the point where cross-integration duplicates get common, the search-and-link habit above is the right amount of process.
If the GitHub side of this is the part giving you trouble specifically, issues piling up faster than anyone can read them, not just the Jira duplicates that come out of it, the underlying triage problem is covered in how to triage GitHub issues at scale. And if your question isn't "is this a duplicate" but "how many customers are actually hitting this Jira bug," that's the adjacent counting problem, covered in how to see which customers are affected by a Jira bug.
One filter, one rule, one sprint
Save one JQL filter scoped to your busiest project, put a one-line rule on your triage doc ("search before you file, from any source"), and confirm your team actually uses Jira's duplicate link type instead of just closing extras with a comment. That alone would have caught two of Kwame's three tickets before either one existed.
