Files
attune/work-summary/2026-02-27-workflow-param-resolution-fix.md
2026-02-27 16:34:17 -06:00

2.4 KiB

Workflow Parameter Resolution Fix

Date: 2026-02-27 Scope: crates/executor/src/scheduler.rs

Problem

Workflow executions triggered via the API failed to resolve {{ parameters.X }} template expressions in task inputs. Instead of substituting the actual parameter value, the literal string "{{ parameters.n }}" was passed to the child action, causing runtime errors like:

ValueError: invalid literal for int() with base 10: '{{ parameters.n }}'

Root Cause

The execution scheduler's process_workflow_execution and advance_workflow methods extracted workflow parameters from the execution's config field using:

execution.config.as_ref()
    .and_then(|c| c.get("parameters").cloned())
    .unwrap_or(json!({}))

This only handled the wrapped format {"parameters": {"n": 5}}, which is how child task executions store their config. However, when a workflow is triggered manually via the API, the config is stored in flat format {"n": 5} — the API places request.parameters directly into the execution's config column without wrapping it.

Because config.get("parameters") returned None for the flat format, workflow_params was set to {} (empty). The WorkflowContext was then built with no parameters, so {{ parameters.n }} failed to resolve. The error was silently swallowed by the fallback in dispatch_workflow_task, which used the raw (unresolved) input when template rendering failed.

Fix

Added an extract_workflow_params helper function that handles both config formats, matching the existing logic in the worker's ActionExecutor::prepare_execution_context:

  1. If config contains a "parameters" key → use that value (wrapped format)
  2. Otherwise, if config is a JSON object → use the entire object as parameters (flat format)
  3. Otherwise → return empty object

Replaced both extraction sites in the scheduler (process_workflow_execution and advance_workflow) with calls to this helper.

Files Changed

  • crates/executor/src/scheduler.rs:
    • Added extract_workflow_params() helper function
    • Updated process_workflow_execution() to use the helper
    • Updated advance_workflow() to use the helper
    • Added 6 unit tests covering wrapped, flat, None, non-object, empty, and precedence cases

Testing

  • All 104 existing executor tests pass
  • 6 new unit tests added and passing
  • No new warnings introduced