Problem
When a flow step calls a sub-flow, the output is accessible via different paths depending on context, and the behavior appears inconsistent. In practice, teams find that some flows require:
$.steps.loadConfig.output.load.output.MY_CONSTANT
While the same sub-flow in a different parent flow requires:
$.steps.loadConfig.response.load.output.MY_CONSTANT
This means flows calling the same sub-flow use different access patterns. Teams end up writing defensive code that tries both:
var cfg = ((($.steps.loadConfig || {}).output || {}).load || {}).output
|| (((($.steps.loadConfig || {}).response || {}).load || {}).output)
|| {};
Real-world impact
In a codebase with 90+ flows, we found both .output. and .response. patterns used for the same shared constants sub-flow. This creates:
- Copy-paste bugs — developers copy from one flow, paste into another, and it breaks because the access path is different
- Wiring regression tests — we maintain external tests specifically to catch this inconsistency
- Defensive boilerplate — every sub-flow consumer needs try-both-paths code
Proposal
Normalize sub-flow output so that $.steps.X.output always works regardless of step type:
- Code step:
$.steps.X.output → the return value ✅ (works today)
- Bash step:
$.steps.X.output → parsed stdout ✅ (works today)
- Flow step:
$.steps.X.output → the sub-flow's final output ❌ (inconsistent today)
- Action step:
$.steps.X.output → the action response ❌ (uses .response today)
If backwards compatibility requires keeping .response, add .output as a canonical alias that always works.
Related
This is an upgrade/consolidation of #47 with concrete evidence from a 90+ flow codebase.
Problem
When a flow step calls a sub-flow, the output is accessible via different paths depending on context, and the behavior appears inconsistent. In practice, teams find that some flows require:
While the same sub-flow in a different parent flow requires:
This means flows calling the same sub-flow use different access patterns. Teams end up writing defensive code that tries both:
Real-world impact
In a codebase with 90+ flows, we found both
.output.and.response.patterns used for the same shared constants sub-flow. This creates:Proposal
Normalize sub-flow output so that
$.steps.X.outputalways works regardless of step type:$.steps.X.output→ the return value ✅ (works today)$.steps.X.output→ parsed stdout ✅ (works today)$.steps.X.output→ the sub-flow's final output ❌ (inconsistent today)$.steps.X.output→ the action response ❌ (uses.responsetoday)If backwards compatibility requires keeping
.response, add.outputas a canonical alias that always works.Related
This is an upgrade/consolidation of #47 with concrete evidence from a 90+ flow codebase.