fix: add env var detection warning to workflow step execution#967
fix: add env var detection warning to workflow step execution#967
Conversation
Workflow step execution now calls detectEnvVarUsageInDefinition on each
model definition before method execution, matching the direct CLI path.
When a definition contains ${{ env.VAR }} expressions, a warning is
emitted so workflow operators know that data stored under the model will
vary by environment.
Changes:
- Add env_var_warning event to WorkflowExecutionEvent and WorkflowRunEvent
- Call detectEnvVarUsageInDefinition in executeModelMethod after model_resolved
- Handle env_var_warning in all three workflow renderers (log, JSON, tree)
- Add env_var_warning to client protocol WorkflowRunEvent
Follow-up to #947
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
There was a problem hiding this comment.
CLI UX Review
Blocking
None.
Suggestions
-
JSON mode silently drops env_var_warning —
JsonWorkflowRunRendererinworkflow_run.ts:247is a no-op forenv_var_warning, while the equivalentJsonModelMethodRunRendererinmodel_method_run.ts:177emits the warning as a JSON object. Users runningworkflow run --jsonin scripts won't see the warning at all. Consider emitting a JSON warning object here for parity with direct model execution. -
Minor log-mode inconsistency —
workflow_run.ts:118useslogger.warn(e.message)whilemodel_method_run.ts:72useslogger.warn("{message}", { message: e.message }). The message contains no placeholders so this is functionally identical, but keeping the template form would be consistent. -
Tree renderer silently drops warning —
workflow_run_tree/state.ts:472handlesenv_var_warningby returning unchanged state (same asmethod_executing), so the interactive TUI shows no indication of the warning. This may be intentional since the tree focuses on step status, but it means the warning is only visible in log mode, not the default TTY experience.
Verdict
PASS — The core feature works correctly: env var warnings now appear during workflow step execution in log mode, matching the behavior of direct CLI execution. The JSON omission is a suggestion rather than a blocker since the warning is already present in log mode.
There was a problem hiding this comment.
Adversarial Review
Critical / High
None.
Medium
None.
Low
-
src/presentation/renderers/workflow_run.ts:247— JSON renderer silently drops env_var_warning: The JSON renderer handlesenv_var_warningas a no-op (() => {}). This means users consuming--jsonoutput will never see these warnings. This is consistent with howmodel_resolvedand other informational events are treated in the JSON renderer (they're all no-ops), so it follows the existing pattern — but it's worth noting that a workflow consumer relying solely on JSON output won't get env var warnings. If this is intentional (warnings are presentation-only, not data), this is fine. -
src/presentation/renderers/workflow_run_tree/state.ts:472-473— tree UI silently ignores env_var_warning: The tree renderer's state reducer returnsstateunchanged forenv_var_warning, meaning the TUI dashboard won't display any visual indication of env var usage. The warning only appears in the log renderer. This is a reasonable choice since the tree view has limited space, but users who only use the TUI won't see the warning. -
src/domain/workflows/execution_service.ts:236—ctx.emitEvent?.()optional chain: IfemitEventis undefined (i.e., the step executor is called without an event sink), the warning is silently skipped. This is consistent with all otherctx.emitEvent?.()calls in the same function (e.g., line 225), so the pattern is correct. Just noting that env var detection still runs even when nobody is listening.
Verdict
PASS — This is a clean, minimal change that adds env_var_warning plumbing through the event pipeline. The new event variant is handled exhaustively in all three renderers (enforced by the EventHandlers<E> mapped type), the mapEvent switch has a never exhaustiveness guard, the domain/client protocol types are structurally compatible, and the detectEnvVarUsageInDefinition function was already reviewed in #964. No logic errors, no security concerns, no resource leaks.
There was a problem hiding this comment.
Code Review
Clean, well-scoped PR that extends the existing env_var_warning pattern from direct CLI execution to workflow step execution. The implementation is consistent with the established pattern in src/libswamp/models/run.ts and src/presentation/renderers/model_method_run.ts.
Blocking Issues
None.
Suggestions
- Test coverage for the new event path: The
env_var_warningemission inexecution_service.ts:234-246and its handling across the three workflow renderers have no new tests. The existingexecution_service_test.tscould be extended with a test that uses a definition containing${{ env.VAR }}expressions and asserts theenv_var_warningevent is emitted. This is non-blocking since the underlyingdetectEnvVarUsageInDefinitionfunction is already tested, and the wiring is straightforward event passthrough.
DDD Review
- The
env_var_warningevent is correctly modeled as a domain execution event in the workflow bounded context, consistent with sibling events (model_resolved,method_executing, etc.). - The event is properly propagated through the layers: domain → libswamp (mapped via
mapEvent) → presentation renderers — maintaining clean layer separation. - The
EnvVarUsageDetailvalue object is appropriately reused from the validation service where it's already defined.
Other Notes
- All three renderers (log, JSON, tree) handle the new event correctly: log renders warnings, JSON silently ignores it (consistent with how
model_resolvedis handled), and tree forwards it to the state reducer which returns state unchanged. - The
mapEventpassthrough inrun.ts:351is correct since the event shape matches between domain and libswamp layers. - The client protocol type in
packages/client/protocol.tscorrectly inlines theenvVarsshape rather than importing from domain internals. - Import boundaries are respected: libswamp-internal code imports from domain (allowed), and presentation/CLI code doesn't directly import from new internal paths.
Summary
Follow-up to #964 (which closed #947). The previous PR explicitly scoped out
env var detection in the workflow path — this PR adds it.
When a model definition contains
${{ env.VAR }}expressions, both direct CLIexecution and workflow step execution now emit the same warning:
Changes
env_var_warningevent toWorkflowExecutionEventandWorkflowRunEventdetectEnvVarUsageInDefinitioninexecuteModelMethodafter model resolutionenv_var_warningin all three workflow renderers (log, JSON, tree)env_var_warningto client protocolWorkflowRunEventTest Plan
deno check,deno lint,deno fmtcleanmodel method runwith${{ env.API_ENDPOINT }}in definition → warning shown ✅workflow runwith same model → identical warning now shown (previously missing) ✅🤖 Generated with Claude Code