-
Notifications
You must be signed in to change notification settings - Fork 296
Description
Context
Observed in production on 2026-03-07. A prd-decomposer workflow created 6 sub-issues from a PRD but the 7th failed handler validation (temporary_id: aw_ui — too short). The safe-outputs step reported success, the workflow dispatched downstream agents, and the missing feature was only discovered by manual audit.
Still reproducible on upstream gh-aw main at 548291897572e4f8007306613039c0e553bf1a32 and in v0.56.0.
Problem
When a safe-output handler returns {success: false}, the handler manager correctly counts the failure in failureCount but only emits core.warning(). It never calls core.setFailed(), so the step exits 0 and the workflow reports success.
This applies both to:
- first-pass handler failures (for example,
create_issuerejecting an invalidtemporary_id) - deferred-message retry failures that come back as
{success: false}on the retry pass
This is distinct from #19017 (permanently deferred items excluded from failureCount). Here, failureCount is already correct — the escalation path is what's missing.
Location
actions/setup/js/safe_output_handler_manager.cjs:316-330— first-pass handler failure capturedactions/setup/js/safe_output_handler_manager.cjs:467-476— deferred retry failure capturedactions/setup/js/safe_output_handler_manager.cjs:898—failureCountcomputedactions/setup/js/safe_output_handler_manager.cjs:927-929—core.warning()only, nocore.setFailed()actions/setup/js/safe_output_handler_manager.cjs:994-995— onlycore.setFailed()is in top-level catch
Reproduction
Minimal workflow config:
safe-outputs:
create-issue: {}Minimal agent output:
{"type":"create_issue","title":"Frontend","body":"Build the frontend","temporary_id":"aw_ui"}Steps:
- Run any workflow that executes the consolidated safe-outputs step with the config above.
- Feed the handler manager the agent output above.
create_issuevalidation rejectstemporary_id: "aw_ui"and returns{success: false, error: "Invalid temporary_id format: 'aw_ui'..."}.safe_output_handler_manager.cjsrecords the failure and computesfailureCount = 1.- The step summary and logs show the failure, but the step still exits with code 0 because
failureCount > 0only triggerscore.warning(). - The job and workflow continue as successful.
Expected behavior
When failureCount > 0, the safe-outputs step should call core.setFailed() so the step, job, and workflow all report failure.
Proposed fix
Add core.setFailed() when failureCount > 0:
if (failureCount > 0) {
core.warning(`${failureCount} message(s) failed to process`);
const failedItems = processingResult.results
.filter(r => !r.success && !r.deferred && !r.skipped && !r.cancelled)
.map(r => ` - ${r.type}: ${r.error}`)
.join('\n');
core.setFailed(`${failureCount} safe output(s) failed:\n${failedItems}`);
}Environment
- Observed in production: v0.52.1-generated workflows
- Still present on: upstream
mainat548291897572e4f8007306613039c0e553bf1a32; also verified inv0.56.0 - Repo:
samuelkahessay/to-do-app-with-weather-and-notification-preferences