Skip to content

safe-outputs: handler failures (success: false) computed in failureCount but never escalated to core.setFailed() #20035

Description

@samuelkahessay

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_issue rejecting an invalid temporary_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 captured
  • actions/setup/js/safe_output_handler_manager.cjs:467-476 — deferred retry failure captured
  • actions/setup/js/safe_output_handler_manager.cjs:898 — failureCount computed
  • actions/setup/js/safe_output_handler_manager.cjs:927-929 — core.warning() only, no core.setFailed()
  • actions/setup/js/safe_output_handler_manager.cjs:994-995 — only core.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:

  1. Run any workflow that executes the consolidated safe-outputs step with the config above.
  2. Feed the handler manager the agent output above.
  3. create_issue validation rejects temporary_id: "aw_ui" and returns {success: false, error: "Invalid temporary_id format: 'aw_ui'..."}.
  4. safe_output_handler_manager.cjs records the failure and computes failureCount = 1.
  5. The step summary and logs show the failure, but the step still exits with code 0 because failureCount > 0 only triggers core.warning().
  6. 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 main at 548291897572e4f8007306613039c0e553bf1a32; also verified in v0.56.0
  • Repo: samuelkahessay/to-do-app-with-weather-and-notification-preferences

Activity

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions