Skip to content

Fix add_labels silently applying no labels - #50637

Merged
pelikhan merged 3 commits into
mainfrom
copilot/fix-add-labels-functionality
Aug 5, 2026
Merged

Fix add_labels silently applying no labels#50637
pelikhan merged 3 commits into
mainfrom
copilot/fix-add-labels-functionality

Conversation

Copilot AI commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

add_labels stopped applying labels: logs report "Successfully added N labels" but nothing appears on the issue/PR.

Root cause

When issue-intent is enabled (the default), the handler passed label objects carrying intent metadata to the REST endpoint:

// sent to github.rest.issues.addLabels
[{ name: "security:low", rationale: "...", confidence: "HIGH", suggest: true }]

issues.addLabels only accepts label name strings. The extra keys make GitHub return 200 while applying nothing. Intent metadata is only supported via the GraphQL updateIssue/LabelUpdateInput path (see update_issue.cjs), not REST addLabels.

Changes

  • add_labels.cjs: send plain label name strings to issues.addLabels; drop the intent-object payload construction and the now-unused issueIntentEnabled local. Validation, dedup, staged preview, and labelsAdded reporting are unchanged.
  • add_labels.test.cjs: update expectations that previously asserted the object payload to expect name strings.

Notes for review

Intent metadata (rationale/confidence/suggest) is no longer forwarded on the add_labels REST call. If per-label intent must be persisted, it should route through the GraphQL mutation rather than REST — out of scope for this regression fix.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

👋 Thanks for working on this bug fix! I can see you're investigating the add_labels functionality regression that started ~Jul 22. Here's what would help this PR move forward:

Current Status:
This is a Draft PR with no code changes yet (0 additions/deletions, 0 files changed). The description references issue #50631 and includes context from the original report.

What's Needed:

  • Add actual code changes — The PR currently has no diff. Once you've identified and fixed the root cause of the add_labels bug, commit the changes to this branch.
  • Add tests — Include test coverage for the fix. Given this is a regression in the safe-outputs labeling logic, add unit tests or integration tests that verify labels are correctly applied to PRs.
  • Update the description — As you've noted in the PR body, you'll update the description as you make progress.

As mentioned in the Contributing Guidelines, this project uses agentic development. Since you're an agent working on this, continue with your investigation and implementation. Once you have code changes, tests, and a clear description, mark the PR as ready for review.

You're on the right track — keep this PR's status updated as you make progress! 🚀

Generated by ✅ Contribution Check · auto · 46.3 AIC · ⌖ 4.76 AIC · ⊞ 8.8K ·

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix add_labels functionality in GitHub Agentic Workflow Fix add_labels silently applying no labels Aug 5, 2026
Copilot AI requested a review from pelikhan August 5, 2026 17:29
@pelikhan

pelikhan commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

@copilot apply fix for Intent metadata (rationale/confidence/suggest) is no longer forwarded on the add_labels REST call. If per-label intent must be persisted, it should route through the GraphQL mutation rather than REST — out of scope for this regression fix.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply fix for Intent metadata (rationale/confidence/suggest) is no longer forwarded on the add_labels REST call. If per-label intent must be persisted, it should route through the GraphQL mut...

Done in a1c0288. When intent metadata (rationale/confidence/suggest) is present and issue_intent is enabled (default), add_labels now routes through the GraphQL updateIssue/LabelUpdateInput mutation (with the update_issue_suggestions feature header), matching update_issue.cjs. Existing issue labels are merged (metadata-free) so add-only semantics are preserved. Plain REST addLabels with name strings is still used when there's no metadata or issue_intent: false.

@pelikhan
pelikhan marked this pull request as ready for review August 5, 2026 17:56
Copilot AI balanced review requested due to automatic review settings August 5, 2026 17:56
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #50637 does not have the 'implementation' label and has 0 new lines of code in business logic directories (only 2 files changed, none in src/, lib/, pkg/, internal/, app/, core/, domain/, services/, or api/).

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

Copilot AI 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.

Pull request overview

Fixes label application failures caused by sending objects to the REST API.

Changes:

  • Sends plain names through REST.
  • Routes intent-bearing labels through GraphQL.
  • Updates tests for both paths.
Show a summary per file
File Description
actions/setup/js/add_labels.cjs Adds REST normalization and GraphQL intent handling.
actions/setup/js/add_labels.test.cjs Updates label payload and GraphQL expectations.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +261 to +264
// Intent metadata is only supported via the GraphQL updateIssue mutation. That
// mutation replaces the issue's label set, so merge the newly requested labels with
// the issue's existing labels to preserve add-only semantics. Existing labels are
// sent without intent metadata; newly requested labels carry their metadata.
Comment on lines +233 to +237
// The REST issues.addLabels endpoint only accepts label name strings; it does not
// support issue-intent metadata (rationale/confidence/suggest). Passing objects with
// those extra keys causes GitHub to return success while silently applying no labels.
// When intent metadata is present, route through the GraphQL updateIssue/LabelUpdateInput
// mutation instead (see update_issue.cjs), which does support intent metadata.
@github-actions github-actions Bot mentioned this pull request Aug 5, 2026

@github-actions github-actions 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.

Skills-Based Review 🧠

Applied /diagnosing-bugs — the root-cause fix is correct and well-tested, but two correctness issues in the new GraphQL path need addressing before merge.

📋 Key Themes & Highlights

Key Themes

  • Redundant REST call: fetchIssueState and the new intent block both call issues.get, doubling the API cost for every intent-label operation.
  • Silent truncation risk: The GraphQL fragment labels(first: 100) can silently cap the after-state label list, causing attachExecutionState to report stale/incomplete data.

Positive Highlights

  • ✅ Root cause correctly identified and fixed: objects with extra keys now route through GraphQL instead of silently failing on REST.
  • ✅ Add-only semantics preserved by merging existing labels before the mutation.
  • ✅ Good regression test coverage: new test for existing-label preservation, and updated assertions on all affected paths.
  • ✅ Clear, accurate comments explaining the REST vs. GraphQL constraint.
> 🧠 *Reviewed using Matt Pocock's skills by [Matt Pocock Skills Reviewer](https://github.com/github/gh-aw/actions/runs/31032398857)* · sonnet46 · 36.7 AIC · ⌖ 13.9 AIC · ⊞ 7.1K > Comment /matt to run again

// mutation replaces the issue's label set, so merge the newly requested labels with
// the issue's existing labels to preserve add-only semantics. Existing labels are
// sent without intent metadata; newly requested labels carry their metadata.
const { data: issueData } = await withRetry(

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.

[/diagnosing-bugs] Redundant issues.get call: fetchIssueState (line 258) already calls github.rest.issues.get unconditionally, then the intent path calls it again here to get node_id and labels. This doubles the REST cost and creates two separate failure points for every intent-label operation.

💡 Suggested fix

Call issues.get once above the if (useIssueIntentPath) block and use the result for both beforeState extraction and the intent path:

const { data: issueData } = await withRetry(
  () => githubClient.rest.issues.get({ owner: repoParts.owner, repo: repoParts.repo, issue_number: itemNumber }),
  RATE_LIMIT_RETRY_CONFIG,
  `get ${contextType} #${itemNumber}`
);
const beforeState = attachExecutionState(extractIssueStateFromData(issueData), ...);
// reuse issueData.node_id and issueData.labels in the intent block

This removes the extra round-trip and makes the failure surface smaller.

@copilot please address this.

{ issueId: issueNodeId, labels: labelIntentUpdates, headers: { "GraphQL-Features": "update_issue_suggestions" } }
),
RATE_LIMIT_RETRY_CONFIG,
`add_labels to ${contextType} #${itemNumber} in ${itemRepo}`

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.

[/diagnosing-bugs] Hard-coded labels(first: 100) cap in the GraphQL response could silently truncate the afterLabels list for issues with more than 100 labels, causing attachExecutionState to report an incorrect post-operation label set.

💡 Suggested fix

Use pagination or, at minimum, add a warning when the response indicates truncation:

// After the mutation response:
const labelPage = result?.updateIssue?.issue?.labels;
if (labelPage?.pageInfo?.hasNextPage) {
  core.warning(`Label list truncated; issue #${itemNumber} has more than 100 labels`);
}
const afterLabels = labelPage?.nodes || [];

Alternatively, bump the fragment to first: 250 (the GitHub API maximum) and add the guard.

@copilot please address this.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 83/100 — Excellent

Analyzed 22 test(s): 20 design, 2 implementation, 0 violation(s).

📊 Metrics (22 tests)
Metric Value
Analyzed 22 (Go: 0, JS: 22)
✅ Design 20 (91%)
⚠️ Implementation 2 (9%)
Edge/error coverage 15 (68%)
Duplicate clusters 1
Inflation No (1.39:1)
🚨 Violations 0
Test File Classification Issues
should add labels using explicit item_number add_labels.test.cjs design_test
should accept structured label entries (intent→GraphQL) add_labels.test.cjs design_test
should send structured label metadata via GraphQL add_labels.test.cjs design_test slight overlap with above
should normalize lowercase confidence add_labels.test.cjs design_test
should preserve existing labels on GraphQL path add_labels.test.cjs design_test
should accept issue_number alias add_labels.test.cjs design_test
should accept pr_number alias add_labels.test.cjs design_test
should accept pull_number alias add_labels.test.cjs design_test
should handle API errors gracefully add_labels.test.cjs design_test
should reject labels starting with '-' add_labels.test.cjs design_test
should truncate labels longer than 64 chars add_labels.test.cjs design_test
should reject invalid non-numeric from context add_labels.test.cjs design_test
should handle numeric string from context payload add_labels.test.cjs design_test
should strip intent metadata when disabled add_labels.test.cjs design_test
should reject plain strings in strict mode add_labels.test.cjs design_test
should filter blocked patterns add_labels.test.cjs design_test
should skip when required_labels missing add_labels.test.cjs design_test
should skip when required_title_prefix missing add_labels.test.cjs design_test
should resolve temporary ID add_labels.test.cjs design_test
should defer on unresolved temporary ID add_labels.test.cjs design_test
should create handler with default config add_labels.test.cjs implementation_test factory smoke test
should create handler with custom config add_labels.test.cjs implementation_test factory smoke test
⚠️ Flagged Tests (1)

should send structured label metadata without requiring a runtime feature (add_labels.test.cjs:164) — design_test, moderate duplication. This test is nearly identical to should accept structured label entries and add normalized label names (same GraphQL mutation assertion, same item_number 456, same confidence: "HIGH"). Consider merging or adding a distinct scenario (e.g., no suggest field) to justify the separate case.

Verdict

Passed. 9% implementation tests (threshold: 30%). The core fix — sending plain label name strings to REST addLabels instead of intent objects — is directly tested and well-covered. The GraphQL intent path has solid edge-case coverage (confidence normalization, existing-label preservation, strict mode enforcement). No violations.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 40.3 AIC · ⌖ 8.32 AIC · ⊞ 7.7K ·
Comment /review to run again

@github-actions github-actions 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.

✅ Test Quality Sentinel: 83/100. 9% implementation tests (threshold: 30%).

@github-actions github-actions 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.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 44 AIC · ⌖ 7.53 AIC · ⊞ 5.4K

// mutation replaces the issue's label set, so merge the newly requested labels with
// the issue's existing labels to preserve add-only semantics. Existing labels are
// sent without intent metadata; newly requested labels carry their metadata.
const { data: issueData } = await withRetry(

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.

Redundant issues.get call — double-fetch on the intent path.

fetchIssueState (line 258) already calls github.rest.issues.get internally to capture the before-state. The intent path then makes a second issues.get call (here) solely to retrieve node_id and existing labels.

This doubles the GitHub API calls on every intent-metadata label add. Either expose the raw issue data from fetchIssueState, or call issues.get once before the fetchIssueState call and derive beforeState from that data:

const { data: issueData } = await withRetry(() => githubClient.rest.issues.get(...), ...);
const beforeState = extractIssueStateFromData(issueData); // reuse same data

@copilot please address this.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please follow up on the latest review feedback on this PR:

  • address the requested changes from the Matt Pocock Skills Reviewer about the GraphQL intent-label path
  • investigate and fix the failing checks: JS Tests (shard 3/4) and PR Code Quality Reviewer
  • refresh the branch if needed and then run the pr-finisher skill

Run: https://github.com/github/gh-aw/actions/runs/31034308996

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 27.8 AIC · ⌖ 5.07 AIC · ⊞ 8.3K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

PR Triage: #50637

Category: bug | Risk: high | Priority Score: 78/100 (impact 40, urgency 23, quality 15)
Recommended action: fast_track
add_labels silently no-op is a high-impact regression to a core safe-output; CI 'agent' job currently failing — verify before merge.

Generated by 🔧 PR Triage Agent · auto · 45.2 AIC · ⌖ 2.9 AIC · ⊞ 8K ·

@pelikhan
pelikhan merged commit d490fe9 into main Aug 5, 2026
46 of 57 checks passed
@pelikhan
pelikhan deleted the copilot/fix-add-labels-functionality branch August 5, 2026 19:05
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please follow up on the latest review feedback on this PR:

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 10.8 AIC · ⌖ 5.72 AIC · ⊞ 8.3K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.85.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'add_labels' does not seem to work anymore since a couple weeks

4 participants