@@ -2030,6 +2030,40 @@ function buildCredentialAuthErrorContext(auditJsonlPathOverride) {
20302030 const templatePath = getPromptPath ( "credential_auth_error.md" ) ;
20312031 return "\n" + renderTemplateFromFile ( templatePath , { providers : providersList } ) ;
20322032}
2033+
2034+ /**
2035+ * Build a context string when assign_to_agent reported assignment errors.
2036+ * Includes remediation guidance for token and Copilot access setup.
2037+ * @param {string } assignmentErrors
2038+ * @returns {string }
2039+ */
2040+ function buildAssignmentErrorsContext ( assignmentErrors ) {
2041+ if ( ! assignmentErrors || ! assignmentErrors . trim ( ) ) {
2042+ return "" ;
2043+ }
2044+
2045+ let context = buildWarningAlertLine ( "Agent Assignment Failed" , "Failed to assign agent to issues or pull requests." ) ;
2046+ context += "\n**Assignment Errors:**\n" ;
2047+
2048+ const errorLines = assignmentErrors . split ( "\n" ) . filter ( line => line . trim ( ) ) ;
2049+ for ( const errorLine of errorLines ) {
2050+ const parts = errorLine . split ( ":" ) ;
2051+ if ( parts . length >= 4 ) {
2052+ const type = parts [ 0 ] ; // "issue" or "pr"
2053+ const number = parts [ 1 ] ;
2054+ const agent = parts [ 2 ] ;
2055+ const error = parts . slice ( 3 ) . join ( ":" ) ;
2056+ context += `- ${ type === "issue" ? "Issue" : "PR" } #${ number } (agent: ${ agent } ): ${ error } \n` ;
2057+ }
2058+ }
2059+
2060+ context += "\nTo resolve this, verify the agent token and Copilot access configuration:\n" ;
2061+ context += "- Configure a valid `GH_AW_AGENT_TOKEN` with `issues: write` and `pull-requests: write` plus active Copilot entitlement\n" ;
2062+ context += "- If your org supports it, add `permissions: { copilot-requests: write }` to use org inference without a personal token\n" ;
2063+ context += "- Docs: https://github.github.com/gh-aw/reference/engines/#github-copilot-default\n\n" ;
2064+
2065+ return context ;
2066+ }
20332067/**
20342068 * Build a context string when assigning the Copilot coding agent to created issues failed.
20352069 * @param {boolean } hasAssignCopilotFailures - Whether any copilot assignments failed
@@ -2699,8 +2733,10 @@ async function main() {
26992733 // in the engine output and sets the agentic_engine_timeout output.
27002734 const isTimedOut = agentConclusion === "timed_out" || agenticEngineTimeout ;
27012735
2702- // Check if there are assignment errors (regardless of agent job status)
2703- const hasAssignmentErrors = parseInt ( assignmentErrorCount , 10 ) > 0 ;
2736+ // Check if there are assignment errors (regardless of agent job status).
2737+ // Use assignment_errors as the single source of truth because it includes
2738+ // both hard failures and skipped(ignore-if-error) assignment errors.
2739+ const hasAssignmentErrors = assignmentErrors . split ( "\n" ) . some ( line => line . trim ( ) ) ;
27042740
27052741 // Check if there are copilot assignment failures for created issues (regardless of agent job status)
27062742 const hasAssignCopilotFailures = parseInt ( assignCopilotFailureCount , 10 ) > 0 ;
@@ -3061,22 +3097,7 @@ async function main() {
30613097 const runId = extractRunId ( runUrl ) ;
30623098
30633099 // Build assignment errors context
3064- let assignmentErrorsContext = "" ;
3065- if ( hasAssignmentErrors && assignmentErrors ) {
3066- assignmentErrorsContext = buildWarningAlertLine ( "Agent Assignment Failed" , "Failed to assign agent to issues due to insufficient permissions or missing token." ) + "\n**Assignment Errors:**\n" ;
3067- const errorLines = assignmentErrors . split ( "\n" ) . filter ( line => line . trim ( ) ) ;
3068- for ( const errorLine of errorLines ) {
3069- const parts = errorLine . split ( ":" ) ;
3070- if ( parts . length >= 4 ) {
3071- const type = parts [ 0 ] ; // "issue" or "pr"
3072- const number = parts [ 1 ] ;
3073- const agent = parts [ 2 ] ;
3074- const error = parts . slice ( 3 ) . join ( ":" ) ; // Rest is the error message
3075- assignmentErrorsContext += `- ${ type === "issue" ? "Issue" : "PR" } #${ number } (agent: ${ agent } ): ${ error } \n` ;
3076- }
3077- }
3078- assignmentErrorsContext += "\n" ;
3079- }
3100+ const assignmentErrorsContext = buildAssignmentErrorsContext ( assignmentErrors ) ;
30803101
30813102 // Build create_discussion errors context
30823103 const createDiscussionErrorsContext = hasCreateDiscussionErrors ? buildCreateDiscussionErrorsContext ( createDiscussionErrors ) : "" ;
@@ -3284,22 +3305,7 @@ async function main() {
32843305 const issueTemplate = fs . readFileSync ( issueTemplatePath , "utf8" ) ;
32853306
32863307 // Build assignment errors context
3287- let assignmentErrorsContext = "" ;
3288- if ( hasAssignmentErrors && assignmentErrors ) {
3289- assignmentErrorsContext = buildWarningAlertLine ( "Agent Assignment Failed" , "Failed to assign agent to issues due to insufficient permissions or missing token." ) + "\n**Assignment Errors:**\n" ;
3290- const errorLines = assignmentErrors . split ( "\n" ) . filter ( line => line . trim ( ) ) ;
3291- for ( const errorLine of errorLines ) {
3292- const parts = errorLine . split ( ":" ) ;
3293- if ( parts . length >= 4 ) {
3294- const type = parts [ 0 ] ; // "issue" or "pr"
3295- const number = parts [ 1 ] ;
3296- const agent = parts [ 2 ] ;
3297- const error = parts . slice ( 3 ) . join ( ":" ) ; // Rest is the error message
3298- assignmentErrorsContext += `- ${ type === "issue" ? "Issue" : "PR" } #${ number } (agent: ${ agent } ): ${ error } \n` ;
3299- }
3300- }
3301- assignmentErrorsContext += "\n" ;
3302- }
3308+ const assignmentErrorsContext = buildAssignmentErrorsContext ( assignmentErrors ) ;
33033309
33043310 // Build create_discussion errors context
33053311 const createDiscussionErrorsContext = hasCreateDiscussionErrors ? buildCreateDiscussionErrorsContext ( createDiscussionErrors ) : "" ;
@@ -3531,6 +3537,7 @@ module.exports = {
35313537 loadToolDenialsExceededEvents,
35323538 buildToolDenialsExceededContext,
35333539 buildCredentialAuthErrorContext,
3540+ buildAssignmentErrorsContext,
35343541 buildAICreditsRateLimitErrorContext,
35353542 buildUnknownModelAICreditsContext,
35363543 hasEngineMaxRunsExceededSignal,
0 commit comments