Why Does a Bug Reported in Slack Need to Become a GitHub Issue Before Devin Can Fix It?
Because the Slack thread and the GitHub issue are doing two different jobs. You can @-mention Devin directly in a Slack channel and get a real answer back in the thread, Cognition's own Slack integration supports exactly that. But answering a question in a thread and fixing a bug in a repo are not the same task, and the second one needs things a Slack message doesn't naturally carry: an exact scope, a reference to the code that handles the working case, and a way to know the fix is done. A GitHub issue is where that structure lives by convention. A Slack thread is where it doesn't.
That gap is why teams that route bugs to Devin still stop and write an issue first, even when Devin is one @-mention away in the same channel the bug was reported in.
What @-mentioning Devin in Slack actually gets you
Devin's Slack integration is real and it's useful, so it's worth being precise about what it does. You can tag @Devin in any channel or thread, run /ask-devin for a quick question, or right-click a message and choose "Ask Devin about this." Devin replies in the thread, and you can steer the session with keywords like mute or archive without leaving Slack. There's one requirement buried in the setup docs that trips people up the first time. Your Slack email has to match your app.devin.ai account email, or the integration can't link the session to your account.
None of that is scoping work. It's a chat interface to a Devin session, and the docs are direct about the tradeoff: "Devin may make mistakes. Please double-check responses." That's a fine warning for a quick question. It's a bigger deal when the "response" is a code change touching a repo other people depend on, which is a different weight class than "can you explain what this error means."
What a GitHub issue carries that the thread doesn't
Devin's GitHub integration is built around the repository, not the conversation. Once an org admin connects it through Settings, Devin gets read-and-write access to a specific set of scopes: contents, so it can commit code, pull requests, so it can open them, and issues, so it can file new ones. When it opens a PR, it looks for a repo-specific template first, checking paths like .github/PULL_REQUEST_TEMPLATE/devin_pr_template.md before falling back to a default format. Once the PR exists, "Devin automatically responds to PR comments as long as the session has not been archived," which is what makes review-and-iterate work as a thread of its own, just one anchored to a diff instead of a conversation.
There's no documented mechanism for assigning Devin to an existing GitHub issue and having that trigger a session. The issue scope covers Devin opening issues, not being invoked from one. So the issue isn't a trigger, it's a container. It's the place where the scope, the reference code, and the success criteria get written down before anyone asks Devin to do anything, in the repo where the fix will land, next to the templates and CI checks that already govern every other PR there.
Cognition's own guidance on instructing Devin effectively is specific about why that structure matters: give it the exact scope of what's broken, links to existing code that already handles the adjacent case correctly, and a measurable definition of done, rather than "make sure it works." A Slack thread rarely has all three sitting in one place. It has a customer's plain-language description, maybe a screenshot, and a few follow-up messages scattered across replies. A GitHub issue is where someone has already done the work of turning that into scope, a repro, and a definition of done, because that's the convention every issue in the tracker follows.
The Vellum Robotics thread that needed rewriting before Devin could use it
Nadia Petrova runs support engineering at Vellum Robotics, which builds fleet-management software for warehouse robots. A customer posted in the shared Slack channel:
Customer (ops lead at a 3PL warehouse): Robot 14 keeps pausing mid-route and requeuing the same pick task. Started this morning after the firmware push. Anyone else seeing this?
Three teammates reacted, one asked "which firmware version," and someone eventually confirmed it was affecting two other robots on the same fleet. Nadia @-mentioned Devin in the thread to ask what the pause behavior usually indicates, and got a reasonable general answer back about requeue logic and a stale route cache. Useful, but not a fix, because Devin's response was reasoning about the category of bug, not the specific route data, firmware version, or the two other affected robots buried three replies down.
So Nadia filed it as a GitHub issue instead:
Issue #4127: Robots 14, 22, 31 requeue pick tasks after firmware v3.8.2 push. Scope: route-cache invalidation on firmware update, not general requeue logic. Reference:
route_cache.py::invalidate_on_update()already handles this for v3.7.x pushes; the same guard is missing for v3.8.2's new cache key format. Repro: attached logs from all three robots, same warehouse, same 40-minute window. Done when: firmware v3.8.2 pushes invalidate the route cache the same way v3.7.x pushes do, verified against the attached logs.
That's the difference. The thread had the same facts, technically, scattered across nine messages and two emoji reactions. The issue put the scope, the reference function, and the done-condition in one place before Devin ever opened the repo. Devin picked it up, found the missing guard, and opened a PR referencing the issue number. Nobody had to explain "which firmware version" a second time.
Where doing this by hand stops working
Writing one issue by hand from one Slack thread is a ten-minute job, and plenty of teams do exactly that and never feel the need for anything else. It stops working the moment the same bug shows up in more than one place. A robot's requeue bug that gets reported in Slack today and shows up as a support ticket from a different customer next week produces two issues, two Devin sessions, and two PRs solving the same problem, because nothing connects the two reports to each other. The person who filed issue #4127 has no way of knowing issue #4203 is the same bug until someone notices the diff looks familiar.
That's also where the requester gets lost. Nadia's issue captured the bug; it didn't automatically capture that the ops lead who first posted, and the teammates who chimed in to confirm robots 22 and 31 had the same symptom, are the people worth telling when the fix ships. That follow-up either happens because someone remembers to scroll back through the original thread, or it doesn't happen at all.
This is the point where an aggregation layer earns its place, and Modem is what we build for it. Modem watches the Slack channels, support tools, and GitHub repos a team already uses, matches new reports against existing topics instead of treating each one as new, and composes the GitHub issue itself, scope, reference code, and the actual customer quotes attached, before handing it to Devin. The three robots in Nadia's example would cluster into one topic the first time the second report came in, and the issue that reaches Devin would already carry every requester's name so the fix goes back to all of them instead of whoever happened to file the first ticket. We build Modem and have an obvious stake in that answer. If Vellum Robotics only ran into a firmware bug like this once a quarter, writing the issue by hand would still be the right call.
Write the issue before you tag anyone
If bugs like this hit your team a few times a year rather than every week, the fix is procedural rather than a tool purchase. The first person to notice a bug in Slack writes it up as a GitHub issue before tagging anyone, using Devin's own instructing guide as the template, scope, reference code, repro, done-condition. For the issue-hygiene half of that habit, our guide to triaging GitHub issues at scale covers the labeling and sweep discipline that keeps a growing issue count from turning into its own backlog. And if the question is less "how do I write the issue" and more "what does Devin need in it," our breakdown of Devin's context requirements goes deeper on that specific list.
