Duplicate Issue Detector
On new issue creation, uses Find Issues By State And Keyword to surface similar open issues, posts a comment listing possible duplicates, and notifies the triager in Teams.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
On every newly-opened GitHub issue, this flow searches the same repository for other open issues whose title closely matches and posts a clickable shortlist of candidates to a Microsoft Teams triage channel. The flow is intentionally non-destructive — it never closes, comments on, or edits the incoming issue; it only surfaces possible duplicates so the person grooming the backlog can act before engineering picks the work up.
Use Case
Backlogs accumulate duplicate issues fast — different reporters describe the same bug with different words, and triagers waste time spotting overlap by hand. This flow catches the obvious cases automatically by leaning on GitHub's own search ranking, so engineers don't end up with two PRs fixing the same thing.
The flow is ideal for teams that:
- Surface possible duplicates within ~3 minutes of issue open.
- Single ranked shortlist posted to Teams, not a wall of noise.
- Never modifies issues — humans stay in the decision loop.
- Fully env-var-driven, so the same solution works against any repo + Teams channel.
Flow Architecture
When an issue is opened
GitHub IssueOpenedPolls every 3 minutes; splitOn = @triggerOutputs()?['body'].
Init 4 variables
InitializeVariablevarGitHubOwner, varGitHubRepository, varTeamsGroupId, varTeamsTriageChannelId from env vars.
Build_Search_Query
ComposeBuilds `"<title>" is:issue is:open repo:<owner>/<repo>` — phrase-quoting forces GitHub to match the title as a phrase.
Search_For_Potential_Duplicates
GitHub SearchIssuesSort=best match, order=desc, per_page=10.
Filter_Out_Current_Issue
QueryRemoves the triggering issue from candidates by comparing number against triggerBody()?['number']; coalesce-resilient.
Check_If_Duplicates_Found
If conditionEvaluates greater(length(filtered), 0).
- Build_Duplicate_List_Html — Select projects each candidate into <li><a href>...</a></li>.
- Post_Duplicate_Alert_To_Triage_Channel — Teams PostMessageToConversation to the configured triage channel.
Empty branch — Teams stays quiet.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_GitHubOwner | String | octocat | GitHub user or org that owns the watched repo. |
| flowlibs_GitHubRepository | String | hello-world | Repository name within that owner. |
| flowlibs_TeamsGroupId | String | — | Teams group (team) GUID where the triage channel lives. |
| flowlibs_TeamsTriageChannelId | String | — | Channel ID within that group to post duplicate alerts. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| GitHub | shared_github | IssueOpened (trigger) SearchIssues |
| Teams | shared_teams | PostMessageToConversation |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Auto-comment with candidates
- Add a GitHub CreateComment action after the Select to also drop the duplicate list onto the issue itself.
- Tighten matching
- Lower per_page from 10 to 3 and require a minimum match score before posting.
- Multi-repo coverage
- Replace the two GitHub env vars with a JSON env var of [{owner, repo}] and Foreach over it.
- Slack instead of Teams
- Swap PostMessageToConversation for the Slack PostMessage action and replace the Teams env vars with a Slack channel ID.
- Closed issue dedup too
- Drop is:open from the Compose query to also surface previously-closed duplicates.
- Trigger frequency
- Change the GitHub trigger recurrence from 3 minutes to a tighter or looser cadence.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Build phrase-quoted search query
Forces phrase match against the original title.
EXPR.02Filter out the triggering issue
Used as the Filter array `where` clause.
EXPR.03Resilient candidate-list source
Handles either response shape from SearchIssues.
EXPR.04Decide whether to alert
Drives the If condition.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.