A Forge app for Jira that recognises the same crash across bug reports by its stack trace, and tells you when a crash that was fixed comes back.
The same crash gets reported many times. QA files it as “Checkout fails with a 500”, support files it as “Customers cannot order to PO boxes”, and an engineer files it as “NullPointerException in shipping quote”. The titles have nothing in common, so text-based duplicate finders miss it. The stack traces are the same failure, but they do not look the same either: line numbers shift with every release, a wrapper exception changes the top of the trace, the bundle hash changes, and the thread and library versions differ.
So triage spends time rediscovering known bugs, and a fix that did not hold goes unnoticed because the new report does not look like the old one.
The app exposes three tools through the Atlassian MCP server (rovo:mcp): find-known-crash, get-crash-for-work-item and list-top-crashes. A developer debugging in an editor can hand the stack trace to their assistant, which asks Jira whether the crash is already tracked and in which version it was fixed, before anyone spends time on it.
skills/check-known-crash/SKILL.md is an open skill file that teaches an agent when and how to use those tools. It works with the Rovo agent in this app and can be added to third-party agents.
| Module | What it does here |
|---|---|
trigger |
Reads a work item when it is created, edited or commented on |
jira:issuePanel |
The Crash Twin panel, shown only on work items that contain a stack trace |
jira:globalPage |
Crash list, trace lookup, and setup |
jira:dashboardGadget |
“Top crashes” gadget |
jira:entityProperty |
Indexes the fingerprint, language, exception type, title and time seen for JQL |
jira:jqlFunction |
issue in sameCrashAs("SHOP-12") |
rovo:agent |
The Crash Twin agent |
action (3) |
The tools the agent uses |
rovo:skill |
check-known-crash |
rovo:mcp |
The same three tools for agents outside Atlassian |
| Forge key-value storage | Settings |
No external services are called. The manifest declares no egress.
Install the app from the Atlassian Marketplace (a Jira administrator does this under Apps > Explore more apps). Then in Jira:
To use the tools from an outside agent, an administrator turns them on under Atlassian Administration > Apps > Sites > your site > Connected apps. The endpoint is https://mcp.atlassian.com/forge/<appId>.
For a chain of exceptions the app uses the one that started the failure: the last “Caused by” in Java, the innermost exception in .NET, the first traceback in Python. For Java it puts back the frames that “… 12 more” stands for, so a wrapped and an unwrapped report of the same failure match.
It then takes the first five frames in the team’s own code, most recent call first, with generated parts removed: lambda and anonymous class numbers, proxy class names, async state machine names, bundle content hashes. Recursion is collapsed so the depth does not matter.
When a trace has no frames in the team’s own code, the app falls back to library frames and says so, because such a match is weaker.
Crashes with different fingerprints that share most of their path are shown as “similar”, never as the same crash.
The app stores a fingerprint and the names of up to twelve frames on each work item. The trace itself stays where the reporter put it. The error message is shown to people who can see the work item and is never used for matching, since messages often contain identifiers and personal data.
All sample data is synthetic.
Runtime dependencies are the Forge SDK packages (@forge/api, @forge/bridge, @forge/kvs, @forge/react, @forge/resolver) and React.
Support: see the Crash Twin privacy and support page. Email vinit@vinitshah.dev.