How to attach a Sentry error to the Intercom conversation that reported it
There's no setting for this, in either direction. Sentry's own integrations directory groups everything it connects to under Source Code, Deployment, Project Management, Notifications, Data, Session Replay, and SSO. GitHub, GitLab, and Azure DevOps sit under Source Code, alongside Bitbucket; Project Management is the category with the actual issue trackers, Jira, Linear, ClickUp, and a handful of others, and that's the closest Sentry gets to a support tool. Intercom isn't on the page in any category.
So attaching the stack trace to the conversation, in practice, means writing a link down yourself rather than pasting the trace itself: the Sentry issue's URL into an internal note on the Intercom conversation, and the conversation's URL into a comment on the Sentry issue. Sentry's issue page confirms comments work this way, "any comments users leave on an issue will also appear" in the Activity tab, so the pointer survives on both sides instead of living in a Slack thread that scrolls away. That two-line habit is the entire trick. Everything past this point is about not having to do it by hand every time.
Why the tag has to come from you
Sentry's search only knows what your code told it. Its event context docs describe Sentry.setTag() as a way to set a searchable, filterable field on an event, and contrast it with Sentry.setContext(), which lets you "attach arbitrary data to an event" that shows up on the issue page but can't be searched or filtered on. Neither populates on its own. If the code path that broke never calls setUser() or a custom tag, the event that fires carries no identity, and there's nothing to search on when the conversation shows up.
The fix is the same one that makes Sentry-to-tracker matching work at all: tag the account, not just the user. A account_id or company_id tag set on login (or read from a service token for background jobs) means the event and the Intercom contact's company attribute point at the same value even when the person who hit the bug and the person who messaged support aren't the same login session.
Making the note write itself
Once that tag exists, the two-line habit above can run without a human in the loop for the common case, where a customer messages Intercom and a matching Sentry issue already exists for their account.
The pieces, none of them exotic. The tricky part isn't any one step, it's that the trigger has to run both directions, because the issue and the conversation can show up in either order:
- Two triggers, not one. A Sentry alert rule that fires on new or reopened issues in the relevant project, and an Intercom webhook that fires on new conversations. Whichever one fires first is the "known" side of the match; the other side is what the lookup goes looking for. Sentry's internal integrations can deliver the alert as a webhook, and the payload carries the issue's title, culprit, level, status,
web_url, and the event's exception data including stack trace frames. What it does not carry is the reporting user's email. Read the docs carefully here; more than one team has built the receiving end assuming the customer's email was in the payload and found out it wasn't. - A lookup step that runs off whichever side fired. On a new Sentry issue, pull the tag off it (via a follow-up call to Sentry's event API, since the alert payload didn't include it) and search Intercom's contact search endpoint for a contact whose company attribute matches. On a new Intercom conversation, do it backward: pull the contact's company attribute and check Sentry for an already-open issue tagged with the same account.
- A note posted back, using Intercom's conversation reply endpoint in its internal-note mode, on whichever conversation the lookup matched. The note carries the issue title and the
web_urlfrom step 1; nobody's re-typing a stack trace into chat.
That's maybe eighty lines of glue code, not a platform. It also only writes in one direction, onto the Intercom conversation; nothing pushes the conversation link back onto the Sentry issue automatically, so the comment on the Activity tab is still a manual step, or a second small script watching Intercom's webhooks for notes matching a known pattern.
The morning the dispatch board froze at Verity Freight
Verity Freight runs routing and dispatch software for regional trucking fleets; a frozen dispatch board means drivers sit at the yard with no load assignments. Naomi Ashworth runs support. Tomas Vukovic is the backend engineer on call for the routing service.
Customer (Intercom, 6:12am): Our dispatch board just went blank when we tried to reassign this morning's loads. Refreshing doesn't fix it. We've got twelve trucks waiting.
Naomi doesn't wait to escalate manually. VRTY-2201 has been open since 6:03am, nine minutes of the webhook processor throwing on every reassignment, but nothing filed a support ticket for it because no customer had said anything yet. The instant her conversation with the customer is created, the lookup runs backward, finds the open issue already tagged to Verity Freight, and drops a note on the conversation before she finishes reading the message: "Sentry issue VRTY-2201, TypeError in webhook processor, 14 events since 6:03am, account_id matches Verity Freight." She pastes the conversation link as a Sentry comment and pings Tomas directly instead of filing a fresh ticket and waiting for triage.
Tomas: Already open, I saw the tag hit the second your conversation showed up. Looks like the load-reassignment webhook is dropping a null truck ID when a driver's shift just ended. Fix is small, pushing now.
Naomi: Appreciate it. Telling them ten minutes, not "we're looking into it."
The stack trace didn't answer the customer's question and the customer's message didn't tell Tomas what broke, but each side had the other's half without asking for it. Naomi replies with a real ETA instead of a placeholder, and Tomas fixes a null check he'd have found from the trace alone anyway, just slower.
Three cases the automation gets wrong
The automation above handles the case it was built for: one account, one obvious tag match, one open conversation. It doesn't hold up past that:
- Shared inboxes break the identity match. A dispatcher's personal email might not be the one attached to the Intercom contact if a shared ops@ address filed the conversation; the account-level tag still helps, but only if the contact search is scoped to company, not just email.
- Multiple open conversations per account mean the script has to guess which thread the note belongs on, or post to all of them and let a human sort it out.
- Nothing dedupes on the Sentry side. If the same null-truck-ID bug throws three differently-worded issues because the stack trace differs by call site, the script posts three separate notes for what support experiences as one outage.
None of that is a reason not to build the eighty-line version. It's a reason to expect a rewrite once the volume crosses a few incidents a week, because the glue code was never meant to dedupe or reconcile identity, just to paste a link faster than a person would.
Where this becomes Modem's job instead
Past that point, Modem covers both integrations directly rather than gluing a webhook to a search endpoint. Modem's Sentry integration reads stack traces and sample events and surfaces "user feedback submitted through Sentry next to the error data it came with." Its Intercom integration pulls conversations, replies, and notes in as they happen and groups them into topics alongside Slack, email, and other channels. Ask Modem about a topic and the linked Sentry data is already attached to it, no account-id tag or contact-search step required on your part, because the matching happens once inside the context graph instead of once per incident inside a script you maintain.
I work on Modem, which is the disclosure worth making before recommending it: I'm not a neutral party here. What I'd actually judge by is engineering time, not integration count. A five-person team with one product and clean account tagging can run the eighty-line version above for a long while without pain. The math flips once dedupe, multiple open conversations, and identity mismatches start costing more hours than the outages themselves, and that's the point where paying for something that already reconciled the identity problem beats maintaining glue code. A related question once the match exists is which other customers hit the same error, and the broader version of this same gap, matching Sentry to any support tool rather than Intercom specifically, is covered in how to connect Sentry errors to the support tickets that reported them.
Start with the tag, not the script
Before building anything, add an account-level tag to every code path that can run without a logged-in user, background jobs and webhooks first, since that's where setUser() quietly never fires. The two-line manual habit, note on the conversation, comment on the issue, works today with no code at all. Automate it once that habit is actually happening several times a day and starting to feel like the job nobody was hired to do.
