Skip to content

Feature request: unassign-from-user safe output handler for removing assignees #15217

@benvillalobos

Description

@benvillalobos

🤖: Bug report submitted by AI

Summary

There is currently no safe output handler for removing assignees from issues. The existing assign-to-user safe output can add assignees, and remove-labels can remove labels, but there is no counterpart for unassigning users.

Use Case

We're building a stale-issue re-triage workflow that:

  1. Runs area-label classification and assignee suggestion when the stale label is applied
  2. Compares the AI-suggested assignee against the issue's current assignee
  3. If they differ, should replace the current assignee with the suggested one

Step 3 is currently impossible via safe outputs. We can add the new assignee with assign-to-user, but we cannot remove the old one. This leads to issues accumulating multiple assignees instead of having the correct one.

Proposed Solution

Add an unassign-from-user (or remove-assignee) safe output, mirroring assign-to-user:

safe-outputs:
  unassign-from-user:
    allowed: [user1, user2]        # Optional: restrict which users can be unassigned
    max: 3                         # Optional: max unassignment operations (default: 1)
    target: "*"                    # Optional: "triggering" (default), "*", or number
    target-repo: "owner/repo"      # Optional: cross-repository

Handler Implementation

The handler would be straightforward — assign_to_user.cjs is ~110 lines, and the unassign version would be nearly identical but call github.rest.issues.removeAssignees instead of addAssignees:

await github.rest.issues.removeAssignees({
  owner: repoParts.owner,
  repo: repoParts.repo,
  issue_number: issueNumber,
  assignees: uniqueAssignees,
});

The handler should use resolveTargetRepoConfig / resolveAndValidateRepo from repo_helpers.cjs from the start (unlike assign_to_user which currently doesn't — see #15216).

MCP Tool Schema

{
  "name": "unassign_from_user",
  "description": "Remove one or more assignees from an issue.",
  "inputSchema": {
    "properties": {
      "assignee": { "type": "string", "description": "Single GitHub username to unassign." },
      "assignees": { "type": "array", "items": { "type": "string" }, "description": "GitHub usernames to unassign." },
      "issue_number": { "type": "number", "description": "Issue number. If omitted, uses the triggering issue." }
    }
  }
}

Compiler Changes

  • Add UnassignFromUserConfig struct embedding BaseSafeOutputConfig and SafeOutputTargetConfig (same pattern as AssignToUserConfig in assign_to_user.go)
  • Add parser, config builder, and handler registration following the existing assign-to-user pattern
  • Add to HANDLER_MAP in safe_output_handler_manager.cjs and safe_output_unified_handler_manager.cjs

Current Workarounds

  1. Accept multiple assignees: Add the correct assignee via assign-to-user, leave the old one. Issue ends up with 2+ assignees.
  2. Use non-read-only GitHub MCP tools: Grant issues: write permission to the agent job and use the GitHub MCP update_issue tool directly. This breaks the safe-outputs security pattern.
  3. Manual cleanup: Have a human remove the old assignee after the workflow runs.

None of these are satisfactory for automated re-triage at scale.

Symmetry with Existing Safe Outputs

The safe outputs system already follows an add/remove pattern for labels:

  • add-labelsremove-labels

The same pattern should exist for assignees:

  • assign-to-userunassign-from-user (missing)

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions