Skip to content

Permanently deferred safe-output items do not fail the workflow #19017

@samuelkahessay

Description

@samuelkahessay

What happens

When a safe-output message references a temporary ID (e.g., #aw_abc) that never gets resolved, the handler manager defers the message on first pass, retries it after all other processing completes, and — if the ID is still unresolved — logs a core.warning() and moves on. The message is never executed.

The warning is present in the logs, but permanently deferred items are not counted as failures. The deferred item is excluded from failureCount computation at safe_output_handler_manager.cjs:896, so the safe-outputs step succeeds even though items were skipped. The workflow passes, and the user has no indication at the workflow-status level that a feature was dropped.

The same warn-only, no-failure pattern is duplicated in the unified handler manager at safe_output_unified_handler_manager.cjs:632 and :1098.

What should happen

Permanently deferred items (still unresolved after retry) should either:

  • Fail the safe-outputs step with a clear error listing which items were dropped and which temp IDs were unresolved, OR
  • Surface as a structured warning in the workflow summary so the user can see what was skipped

Where in the code

All references are to main at 2d91393f3.

Temporary ID validation:

  • temporary_id.cjs:58 — temp IDs must match aw_ + 3-8 alphanumeric characters
  • temporary_id.cjs:242-297resolveIssueNumber() returns {resolved: null, wasTemporaryId: true, errorMessage: "...not found in map"} when a valid temp ID isn't in the resolution map

Deferral on first pass:

  • safe_output_handler_manager.cjs:332-348 — messages with unresolved temp IDs return {deferred: true}, tracked in deferredMessages array
  • link_sub_issue.cjs:76-94 — returns {deferred: true} when parent or child temp IDs are unresolved

Permanent deferral on retry (not counted as failure):

  • safe_output_handler_manager.cjs:479 — if retry still returns {deferred: true}, logs core.warning() and continues to next deferred message
  • safe_output_handler_manager.cjs:896 — computes failureCount from results, but excludes deferred items, so step passes

Duplicated pattern (unified handler):

  • safe_output_unified_handler_manager.cjs:632 — same warn-only, no-failure retry
  • safe_output_unified_handler_manager.cjs:1098 — same warn-only, no-failure retry

Workflow integration:

  • compiler_safe_outputs_steps.go:398 — invokes the handler manager; relies on its exit code to determine success

Evidence

Production:

  • In a 4-agent concurrent pipeline (v0.50.7), a decomposed feature set had a link_sub_issue message referencing a parent temp ID that was never resolved (the parent issue creation failed earlier in the pipeline)
  • The safe-outputs step passed successfully despite the feature being dropped
  • We discovered the missing feature only by manually auditing created issues against the original spec

Source-level verification (2026-03-01, main at 2d91393f3):

  • Confirmed safe_output_handler_manager.cjs:479 logs warning only, does not fail
  • Confirmed safe_output_handler_manager.cjs:896 excludes deferred from failure count
  • Confirmed same pattern duplicated in unified handler manager at :632 and :1098

Proposed fix

Permanently deferred items (still {deferred: true} after retry) should be treated as failures:

  • Mark their results as failures so they are included in the failureCount computation at :896, or
  • Fail the safe-outputs step if any items remain deferred after the retry pass

Either approach ensures the workflow does not report success when items were dropped. The same change should be applied to the unified handler at :632 and :1098.

Impact

Frequency: Low-medium — requires a temp ID to be generated but never resolved (upstream creation must fail first). More likely in complex decompositions with many cross-references.
Cost: Very high when it hits — features are dropped from the output without failing the workflow. The user sees a successful run and has no reason to audit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions