-
Notifications
You must be signed in to change notification settings - Fork 278
Description
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 matchaw_+ 3-8 alphanumeric characterstemporary_id.cjs:242-297—resolveIssueNumber()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 indeferredMessagesarraylink_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}, logscore.warning()and continues to next deferred messagesafe_output_handler_manager.cjs:896— computesfailureCountfrom results, but excludes deferred items, so step passes
Duplicated pattern (unified handler):
safe_output_unified_handler_manager.cjs:632— same warn-only, no-failure retrysafe_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_issuemessage 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:479logs warning only, does not fail - Confirmed
safe_output_handler_manager.cjs:896excludes deferred from failure count - Confirmed same pattern duplicated in unified handler manager at
:632and: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
failureCountcomputation 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.