Skip to content

[cloclo] fix: resolve temporary IDs in add_labels and remove_labels handlers#21058

Merged
pelikhan merged 2 commits intomainfrom
fix/add-labels-temporary-id-resolution-de341fe7cdf04f26
Mar 15, 2026
Merged

[cloclo] fix: resolve temporary IDs in add_labels and remove_labels handlers#21058
pelikhan merged 2 commits intomainfrom
fix/add-labels-temporary-id-resolution-de341fe7cdf04f26

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Mar 15, 2026

Summary

Implements the recommended Option 1: temporary ID resolution in the add_labels (and remove_labels) safe output handlers, consistent with add_comment behavior.

Root Cause

When an agent creates an issue with create_issue and assigns it a temporary_id: aw_report1, then uses add_labels with item_number: aw_report1, the handler fails with:

##[error]✗ Message 6 (add_labels) failed: Invalid item number: aw_report1

This happened because add_labels.cjs (and remove_labels.cjs) used parseInt(String(message.item_number), 10) which returns NaN for temporary ID strings.

Changes

  • add_labels.cjs: Import resolveRepoIssueTarget + loadTemporaryIdMapFromResolved from temporary_id.cjs; use them to resolve item_number before processing. Returns deferred: true when the temporary ID hasn't been resolved yet (so the handler manager retries after the first pass).

  • remove_labels.cjs: Same fix applied.

  • safe_output_validation_config.go: Changed item_number for add_labels and remove_labels from IssueOrPRNumber: true to IssueNumberOrTemporaryID: true so temporary ID strings pass Go-level validation.

  • temporary_id.cjs: Added item_number to the idFields array in extractTemporaryIdReferences, so the scheduler can detect and defer add_labels/remove_labels messages that depend on as-yet-unresolved temporary IDs.

  • add_labels.test.cjs: Added tests for temporary ID resolution — resolved temporary ID, deferred (unresolved), and hash-prefix #aw_report1 formats.

  • remove_labels.test.cjs: Same tests added for remove_labels.

  • temporary_id.test.cjs: Added tests for item_number field in extractTemporaryIdReferences, including verification that numeric item_number values produce no temporary ID references.

  • *.lock.yml: Recompiled workflow lock files to reflect the issueOrPRNumberissueNumberOrTemporaryId schema change.

🤖 Generated with Claude Code via /cloclo


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

The add_labels and remove_labels safe output handlers were using parseInt()
to parse item_number, causing "Invalid item number: aw_report1" errors when
agents referenced issues created earlier in the same run via temporary IDs.

This fix implements temporary ID resolution consistent with add_comment:
- add_labels.cjs: import resolveRepoIssueTarget/loadTemporaryIdMapFromResolved
  from temporary_id.cjs and resolve item_number before parsing
- remove_labels.cjs: same fix applied
- safe_output_validation_config.go: change item_number field for add_labels
  and remove_labels from IssueOrPRNumber to IssueNumberOrTemporaryID to allow
  temporary ID strings to pass validation
- temporary_id.cjs: add item_number to the idFields checked by
  extractTemporaryIdReferences so the scheduler can detect and defer
  add_labels/remove_labels messages with unresolved temporary ID dependencies

Fixes #21035

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@pelikhan
Copy link
Contributor

@copilot update tests

…, and temporary_id

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

Copilot AI commented Mar 15, 2026

@copilot update tests

Added tests in commit 6f30a64:

  • add_labels.test.cjs: 3 new tests — resolved temporary ID, deferred (unresolved), and hash-prefix #aw_report1
  • remove_labels.test.cjs: same 3 tests for remove_labels
  • temporary_id.test.cjs: 3 new tests for item_number field in extractTemporaryIdReferences (including numeric item_number producing no refs)

Also included the missing lock.yml updates that reflect the IssueNumberOrTemporaryID schema change.

Copilot AI requested a review from pelikhan March 15, 2026 13:08
@pelikhan pelikhan marked this pull request as ready for review March 15, 2026 13:12
Copilot AI review requested due to automatic review settings March 15, 2026 13:12
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Resolves failures when add_labels / remove_labels receive a temporary ID (e.g., aw_report1) in item_number, by adding temporary-ID resolution + deferral behavior consistent with other handlers.

Changes:

  • Resolve item_number via temporary ID map in add_labels.cjs and remove_labels.cjs, returning { deferred: true } when unresolved.
  • Expand temporary-ID dependency detection (extractTemporaryIdReferences) to include item_number, and add/extend unit tests.
  • Update safe-output validation schema (issueOrPRNumberissueNumberOrTemporaryId) and recompile workflow lock files accordingly.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/workflow/safe_output_validation_config.go Updates schema flags so item_number can be a temporary ID for label handlers.
actions/setup/js/temporary_id.cjs Adds item_number to dependency extraction field list.
actions/setup/js/temporary_id.test.cjs Adds tests for extracting temporary IDs from item_number (including #-prefixed).
actions/setup/js/add_labels.cjs Resolves temporary IDs for item_number and defers when unresolved.
actions/setup/js/add_labels.test.cjs Adds tests for resolved/deferred temporary IDs and #aw_... format.
actions/setup/js/remove_labels.cjs Mirrors temporary ID resolution/deferral logic for remove-labels handler.
actions/setup/js/remove_labels.test.cjs Adds tests for resolved/deferred temporary IDs and #aw_... format.
.github/workflows/smoke-project.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/smoke-gemini.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/smoke-copilot.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/smoke-copilot-arm.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/smoke-codex.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/smoke-claude.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/scout.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/pr-triage-agent.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/poem-bot.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/issue-triage-agent.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/draft-pr-cleanup.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/contribution-check.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/code-scanning-fixer.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/auto-triage-issues.lock.yml Regenerated lock to reflect schema key rename.
.github/workflows/ai-moderator.lock.yml Regenerated lock to reflect schema key rename.

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

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +551 to +567
it("should resolve temporary ID with hash prefix in item_number", async () => {
const handler = await main({ max: 10 });
const addLabelsCalls = [];

mockGithub.rest.issues.addLabels = async params => {
addLabelsCalls.push(params);
return {};
};

const result = await handler(
{
item_number: "#aw_report1",
labels: ["enhancement"],
},
{ aw_report1: { repo: "test-owner/test-repo", number: 99 } }
);

Comment on lines +572 to +588
it("should resolve temporary ID with hash prefix in item_number", async () => {
const handler = await main({ max: 10 });
const removeLabelCalls = [];

mockGithub.rest.issues.removeLabel = async params => {
removeLabelCalls.push(params);
return {};
};

const result = await handler(
{
item_number: "#aw_report1",
labels: ["enhancement"],
},
{ aw_report1: { repo: "test-owner/test-repo", number: 99 } }
);

Fields: map[string]FieldValidation{
"labels": {Required: true, Type: "array", ItemType: "string", ItemSanitize: true, ItemMaxLength: 128},
"item_number": {IssueOrPRNumber: true},
"item_number": {IssueNumberOrTemporaryID: true},

// Check for other resolution errors
if (resolvedTarget.errorMessage || !resolvedTarget.resolved) {
const error = `Invalid item number: ${message.item_number}`;

// Check for other resolution errors
if (resolvedTarget.errorMessage || !resolvedTarget.resolved) {
const error = `Invalid item number: ${message.item_number}`;
@pelikhan pelikhan merged commit d7a9bfe into main Mar 15, 2026
85 checks passed
@pelikhan pelikhan deleted the fix/add-labels-temporary-id-resolution-de341fe7cdf04f26 branch March 15, 2026 13:21
@github-actions
Copy link
Contributor Author

Hey @github-actions[bot] 👋 — great work on this fix! Resolving temporary IDs in add_labels and remove_labels is exactly the right approach, keeping the behavior consistent with how add_comment already handles the aw_* pattern.

A quick checklist rundown:

Check Result
On-topic ✅ Direct bug fix for temporary ID resolution in safe-output handlers
Follows process ✅ Core-team agent PR via /cloclo
Focused ✅ Single coherent fix — source changes + auto-recompiled lock files
New dependencies ✅ None added
Tests ✅ 166 new test lines across add_labels.test.cjs, remove_labels.test.cjs, and temporary_id.test.cjs
Description ✅ Detailed root-cause analysis, change breakdown, and rationale

Verdict: 🟢 Aligned — looks ready for maintainer review. The three scenarios covered by the new tests (resolved temporary ID, deferred/unresolved, and hash-prefix #aw_report1) give solid confidence in the fix. The temporary_id.cjs change to include item_number in idFields is a nice defensive touch that ensures the scheduler defers messages correctly before the issue number is even available.

Generated by Contribution Check ·

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.

3 participants