Skip to content

BUG: strategy expansion discarded — raw body stored instead of expanded workflow (P0) #36

Description

@addadi

Bug: strategy expansion discarded — raw body stored instead of expanded workflow

Severity: P0 — all strategy features (sequential, parallel) are broken by this
Filed: 2026-07-28
Sibling: nullboiler-62s (parallel+reduce type error), nullboiler-9x1 (sequential chain order)

Summary

When submitting a workflow with "strategy": "sequential" via POST /runs, the expandStrategy function runs correctly — it adds depends_on between consecutive steps via applyChain. But the expanded steps are discarded. The API stores the raw HTTP request body as workflow_json, not the expanded version.

The engine then reads the raw body at runtime, sees no depends_on on any step, synthesizes all steps as graph roots (no edges between them), and dispatches them all as independent nodes.

Root cause

src/api.zig:585-586:

// Insert run — workflow_json = the original body (frozen snapshot)
ctx.store.insertRun(run_id, idempotency_key, "running", body, input_json, callbacks_json) catch {

body = raw HTTP request body. The expanded steps from expandStrategy (line 537, effective_steps) are used ONLY for step DB prepopulation (line 613). They are NOT serialized back into the stored workflow_json.

Evidence

Submitted workflow with "strategy": "sequential" and 3 steps. DB query:

SELECT workflow_json FROM runs WHERE id='05dcb8a3-...';

Result: original JSON with "strategy": "sequential" still present, all steps have no depends_on. The applyChain output was lost.

Fix

Build the workflow JSON from expanded steps (with depends_on), not from raw body. The expanded workflow should:

  1. Drop the strategy field (consumed by expansion)
  2. Use effective_steps (with depends_on from applyChain)
  3. Preserve input, callbacks, and other top-level fields

Code location: src/api.zig around line 585. Replace body with a rebuilt JSON that uses effective_steps.

Acceptance

  • Stored workflow_json has depends_on on steps when strategy: "sequential" is used
  • Stored workflow_json does NOT have strategy field (consumed)
  • Sequential chain enforced: step B doesn't dispatch until step A completes
  • Manual depends_on (no strategy) still works (regression check)
  • Parallel strategy + reduce works (regression check for nullboiler-62s)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions