Skip to content

fix: refetch issue state before final assignment decision #2431

Closed
iron-prog wants to merge 1 commit into
hiero-ledger:mainfrom
iron-prog:fix/2230-refetch-issue-state-before-assign
Closed

fix: refetch issue state before final assignment decision #2431
iron-prog wants to merge 1 commit into
hiero-ledger:mainfrom
iron-prog:fix/2230-refetch-issue-state-before-assign

Conversation

@iron-prog

Copy link
Copy Markdown
Contributor

The GFI and beginner /assign bots decided whether to assign based on context.payload.issue, a snapshot from the original webhook payload. Under concurrency, a queued run could still see a stale assignees/ labels/state and call addAssignees on an issue that was already assigned, closed, or relabeled.

Both bots now refetch the issue via github.rest.issues.get() right before the final assignment decision and recheck assignees, state, and label against that fresh data. If the refetch fails, the bot aborts rather than decide on stale data.

Regression tests added under tests/jest/ (repo's existing Jest harness, wired into test-scripts.yml) covering: stale-but-now-assigned, refetch failure, label removed, and issue closed — for both bots.

Closes #2230

Description:

Refetch current issue state from the GitHub API before the GFI and beginner assignment bots make their final addAssignees decision, instead of trusting the original webhook payload.

  • Refetch the issue via github.rest.issues.get() immediately before assignment in the GFI bot
  • Refetch the issue via github.rest.issues.get() immediately before assignment in the beginner bot
  • Recheck assignees, state, and label against the fresh data (not the stale webhook payload) in both bots
  • Abort safely without assigning if the refetch itself fails, rather than deciding on stale data
  • Add regression tests under .github/scripts/__tests__/jest/ (the repo's existing Jest harness, wired into test-scripts.yml) covering: stale-but-now-assigned, refetch failure, label removed, and issue closed — for both bots

Notes for reviewer:

The GFI and beginner /assign bots previously decided whether to assign based on context.payload.issue, a snapshot from the original issue_comment webhook payload. Under concurrency, a queued run could still see stale assignees/labels/state and call addAssignees on an issue that had already been assigned, closed, or relabeled by an earlier run.

Ran the full existing test suite locally after these changes — all passing, no regressions:

Related issue(s):
Fixes #2230

Notes for reviewer:

Checklist

  • Documented (Code comments, README, etc.)
  • Tested (unit, integration, etc.)

@iron-prog
iron-prog requested review from a team as code owners July 11, 2026 15:53
@iron-prog iron-prog changed the title fix: refetch issue state before final assignment decision (#2230) fix: refetch issue state before final assignment decision Jul 11, 2026
…er#2230)

The GFI and beginner /assign bots decided whether to assign based on
context.payload.issue, a snapshot from the original webhook payload.
Under concurrency, a queued run could still see a stale assignees/
labels/state and call addAssignees on an issue that was already
assigned, closed, or relabeled.

Both bots now refetch the issue via github.rest.issues.get() right
before the final assignment decision and recheck assignees, state,
and label against that fresh data. If the refetch fails, the bot
aborts rather than decide on stale data.

Regression tests added under __tests__/jest/ (repo's existing Jest
harness, wired into test-scripts.yml) covering: stale-but-now-assigned,
refetch failure, label removed, and issue closed — for both bots.

Closes hiero-ledger#2230

Signed-off-by: iron-prog <dt915725@gmail.com>
@iron-prog
iron-prog force-pushed the fix/2230-refetch-issue-state-before-assign branch from c1e28a3 to 3eb0bc9 Compare July 11, 2026 15:56
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@iron-prog, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0aec53d4-e129-450e-8bf7-fcc9f6108884

📥 Commits

Reviewing files that changed from the base of the PR and between c1e28a3 and 3eb0bc9.

📒 Files selected for processing (3)
  • .github/scripts/__tests__/jest/bot-assignment-fresh-issue.test.js
  • .github/scripts/bot-beginner-assign-on-comment.js
  • .github/scripts/bot-gfi-assign-on-comment.js

Walkthrough

Both assignment bots now refetch issue data before assigning, validate the fresh issue state and labels, and use current assignees for duplicate-assignment handling. A Jest suite covers stale payloads, fetch failures, removed labels, and closed issues.

Changes

Fresh Issue Assignment

Layer / File(s) Summary
Fresh issue validation in assignment flows
.github/scripts/bot-gfi-assign-on-comment.js, .github/scripts/bot-beginner-assign-on-comment.js
Both /assign flows fetch the current issue, stop on fetch errors, closed issues, or missing labels, and use fresh assignees when deciding whether to assign or comment.
Stale payload regression coverage
.github/scripts/__tests__/jest/bot-assignment-fresh-issue.test.js
Adds mocked GitHub responses and tests for already-assigned, fetch-error, missing-label, and closed-issue scenarios for both bots.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Requester
  participant AssignmentBot
  participant GitHubREST
  Requester->>AssignmentBot: Send /assign comment
  AssignmentBot->>GitHubREST: Fetch current issue
  GitHubREST-->>AssignmentBot: Return fresh labels, state, and assignees
  AssignmentBot->>GitHubREST: Create comment or add assignee
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: refetching issue state before assignment decisions.
Description check ✅ Passed The description matches the changeset and explains the refetch logic and regression tests.
Linked Issues check ✅ Passed The changes satisfy #2230 by refetching fresh issue state, rechecking assignees/labels/state, and skipping assignment when already assigned.
Out of Scope Changes check ✅ Passed The diff stays focused on the assignment bots and their regression tests, with no obvious unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
📋 Issue Planner

Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).

View plan for ticket: #2230

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.github/scripts/bot-gfi-assign-on-comment.js (2)

355-367: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Wrap the "already assigned" createComment in a granular try/catch for resilience.

The beginner bot wraps this same operation in a try/catch (lines 299–313), logging a contextual error and continuing. Here, a createComment failure propagates to the outer catch which re-throws, failing the workflow over a non-critical notification. As per coding guidelines for .github/scripts/**/*.js, async operations should be wrapped in try/catch with contextual errors.

🛡️ Proposed fix
         if (freshIssue.assignees?.length > 0) {
             console.log('[gfi-assign] Exit: issue already assigned');

-            await github.rest.issues.createComment({
-                owner,
-                repo,
-                issue_number: issueNumber,
-                body: commentAlreadyAssigned(requesterUsername, freshIssue),
-            });
+            try {
+                await github.rest.issues.createComment({
+                    owner,
+                    repo,
+                    issue_number: issueNumber,
+                    body: commentAlreadyAssigned(requesterUsername, freshIssue),
+                });
+                console.log('[gfi-assign] Posted already-assigned comment');
+            } catch (error) {
+                console.error('[gfi-assign] Failed to post already-assigned comment:', {
+                    message: error.message,
+                    status: error.status,
+                    issueNumber,
+                });
+            }

             console.log('[gfi-assign] Posted already-assigned comment');
             return;
         }

Source: Path instructions


308-367: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Refetch logic is duplicated across both bots with divergent error handling. Both bots independently implement the same refetch-then-validate pattern (fetch fresh issue → abort on error → check closed → check label → check assignees), but with inconsistent error handling: the GFI bot's "already assigned" createComment is not wrapped in a granular try/catch (error re-throws, failing the workflow), while the beginner bot's equivalent is wrapped and logged gracefully. Extracting a shared helper would eliminate this duplication and enforce consistent error handling.

  • .github/scripts/bot-gfi-assign-on-comment.js#L308-L367: Extract the refetch + closed/label/assignee validation into a shared helper (e.g., fetchFreshIssueState), parameterizing the label-check function and "already assigned" comment body. Wrap the createComment at line 358 in a granular try/catch within the helper or at the call site.
  • .github/scripts/bot-beginner-assign-on-comment.js#L259-L315: Replace the inline refetch logic with a call to the shared helper, passing the beginner label check and already-assigned comment builder.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3d8d765b-efe8-41e1-99ac-947429732cbf

📥 Commits

Reviewing files that changed from the base of the PR and between 92e7bcd and c1e28a3.

📒 Files selected for processing (3)
  • .github/scripts/__tests__/jest/bot-assignment-fresh-issue.test.js
  • .github/scripts/bot-beginner-assign-on-comment.js
  • .github/scripts/bot-gfi-assign-on-comment.js

Comment on lines +82 to +199
it('GFI bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);

await runGfiAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});

it('GFI bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});

await runGfiAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});

it('GFI bot exits when the fresh issue is no longer a Good First Issue', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);

await runGfiAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});

it('GFI bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);

await runGfiAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});

it('beginner bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);

await runBeginnerAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});

it('beginner bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});

await runBeginnerAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});

it('beginner bot exits when the fresh issue no longer has the beginner label', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);

await runBeginnerAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});

it('beginner bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);

await runBeginnerAssignBot({ github, context });

expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a positive test case verifying the bot assigns when all conditions are valid.

All 8 test cases cover negative scenarios (bot should NOT assign). A positive case — fresh issue is open, labeled, unassigned, and under the assignment limit — would verify the refetch logic doesn't break the happy path and that addAssignees is called with the correct parameters.

♻️ Suggested positive test cases
+  it('GFI bot assigns when fresh issue is open, labeled, and unassigned', async () => {
+    const context = createContext({
+      labelName: 'Good First Issue',
+      payloadAssignees: [],
+      freshAssignees: [],
+    });
+    const { github, calls } = createGithubMock(context);
+
+    await runGfiAssignBot({ github, context });
+
+    expect(calls.assignees.length).toBe(1);
+    expect(calls.assignees[0].assignees).toEqual(['new-contributor']);
+  });
+
+  it('beginner bot assigns when fresh issue is open, labeled, and unassigned', async () => {
+    const context = createContext({
+      labelName: 'skill: beginner',
+      payloadAssignees: [],
+      freshAssignees: [],
+    });
+    const { github, calls } = createGithubMock(context);
+
+    await runBeginnerAssignBot({ github, context });
+
+    expect(calls.assignees.length).toBe(1);
+    expect(calls.assignees[0].assignees).toEqual(['new-contributor']);
+  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('GFI bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});
it('GFI bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('GFI bot exits when the fresh issue is no longer a Good First Issue', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('GFI bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});
it('beginner bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot exits when the fresh issue no longer has the beginner label', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
});
it('GFI bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});
it('GFI bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('GFI bot exits when the fresh issue is no longer a Good First Issue', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('GFI bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'Good First Issue',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);
await runGfiAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot does not assign when webhook payload is stale but issue is now assigned', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshAssignees: [{ login: 'current-assignee' }],
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(1);
expect(calls.comments[0].body).toMatch(/already assigned/i);
expect(calls.comments[0].body).toMatch(/@current-assignee/);
});
it('beginner bot exits safely when fresh issue fetch fails before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
});
const { github, calls } = createGithubMock(context, {
freshIssueError: Object.assign(new Error('GitHub API unavailable'), { status: 503 }),
});
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot exits when the fresh issue no longer has the beginner label', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshLabels: [{ name: 'help wanted' }],
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
it('beginner bot exits when the fresh issue is closed before assignment', async () => {
const context = createContext({
labelName: 'skill: beginner',
payloadAssignees: [],
freshState: 'closed',
});
const { github, calls } = createGithubMock(context);
await runBeginnerAssignBot({ github, context });
expect(calls.assignees.length).toBe(0);
expect(calls.comments.length).toBe(0);
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, worth adding

@github-actions github-actions Bot added open to community review PR is open for community review and feedback queue:junior-committer PR awaiting initial quality review labels Jul 11, 2026

// --- ASSIGNMENT LOGIC ---
if (issue.assignees && issue.assignees.length > 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new "refetch → check closed → check label → check assignees" block (~25-30 lines) is added twice....once here, once in bot-gfi-assign-on-comment.js (lines 309-355)...nearly identical in structure. A shared helper (e.g. refetchIssueOrAbort(github, owner, repo, issueNumber, logPrefix), following the existing shared/labels.js pattern already used by both files) would collapse this into one implementation instead of two.

The two copies have already diverged slightly: the GFI bot's catch-block logs {message, status, issueNumber} (line 324), this one only logs {issue, message}, no status (line 272). Small, but it's the kind of drift that happens specifically because the logic is duplicated rather than shared.

@Mounil2005

Copy link
Copy Markdown
Contributor

The jest suite mocks github.rest.issues.get(), so it verifies the logic branches correctly but doesn't exercise the real GitHub Actions run end-to-end. Did you test this on a fork? Labeling a test issue, commenting /assign, and confirming the flow works against the real API? If you have a fork where you already ran through it, could you share the link?

(Side note: both workflows already have a concurrency: group that serializes runs per repo/issue, so this refetch is the complete fix for the race in #2230, not just a mitigation, permissions are fine too, issues: write already covers the new get() call. Just want to see the actual end-to-end flow run once on a live fork before merge.)

@aceppaluni

Copy link
Copy Markdown
Contributor

HI @iron-prog Thank you very much for submitting this work.

I would like to apologize for the confusion. The issue is currently assigned to someone and should not have been assigned to more then one person without having an initial conversation with both parties.

Therefore I will need to close this PR for now. If the issue is deemed free then this PR can be reopened. :)

Thank you!

@aceppaluni aceppaluni closed this Jul 13, 2026
@iron-prog
iron-prog deleted the fix/2230-refetch-issue-state-before-assign branch July 14, 2026 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

open to community review PR is open for community review and feedback queue:junior-committer PR awaiting initial quality review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Assignment bots should refetch issue state before final assignment decision

5 participants