tinyhumansai/openhuman · error

workflow scheduler graph compile failed: {e}

Error message

workflow scheduler graph compile failed: {e}

What it means

Thrown when GraphBuilder::compile() rejects the workflow scheduler graph's topology (graph.rs:137). compile() validates that set_entry("dispatch") and set_finish("done") reference registered nodes, that every with_goto([...]) target exists, and that command-emitting nodes are marked with mark_command_routing. Because dispatch/run_phase/done are all registered in the same hardcoded function, this error signals an internal invariant break in the scheduler module (or an incompatible tinyagents graph API change), not user configuration.

Source

Thrown at src/openhuman/agent/orchestration/workflow_runs/graph.rs:137

                        .with_goto(["dispatch"]),
                )),
                PhaseExecOutcome::Terminated => {
                    Ok(NodeResult::Command(Command::default().with_goto(["done"])))
                }
            }
        }
    });

    let graph = builder
        .add_node("done", |_s: SchedulerState, _c: NodeContext| async move {
            Ok(NodeResult::Update(SchedulerUpdate::Noop))
        })
        .set_entry("dispatch")
        .mark_command_routing("dispatch")
        .mark_command_routing("run_phase")
        .set_finish("done")
        .compile()
        .map_err(|e| anyhow!("workflow scheduler graph compile failed: {e}"))?
        // Bound the dispatch⇄run_phase cycle as a backstop to the DAG's own
        // termination: `dispatch` is visited once per phase plus a final
        // no-phase visit, `run_phase` once per phase. A validated DAG always
        // drains, so this only guards a malformed definition.
        .with_recursion_policy(RecursionPolicy {
            max_visits_per_node: Some(phase_count + 2),
            max_total_steps: (phase_count + 1) * 3 + 16,
            ..RecursionPolicy::default()
        });
    Ok(graph)
}

/// Topologically walk the phase DAG on a `tinyagents` conditional-routing graph
/// (issue #4249, Phase 4): a `dispatch` node selects the next runnable phase and
/// a `run_phase` node executes it, looping `dispatch ⇄ run_phase` until no phase
/// remains, then routing to `done`:
///
/// ```text

View on GitHub (pinned to a221052e0d)

Solutions

  1. Diff every with_goto target and set_entry/set_finish name against the add_node names in build_scheduler_graph — they must match exactly
  2. Add/keep a unit test calling scheduler_graph_topology() (same builder, stub effects) so topology drift fails CI instead of runtime
  3. If it appears after a tinyagents version bump, read its compile() rules for newly required marks such as mark_command_routing
  4. Treat any occurrence in a shipped build as a bug: capture the backtrace and file an issue

Example fix

// before — goto target typo, no such node
Command::default().with_goto(["run_phases"])

// after — matches add_node("run_phase", ...)
Command::default().with_goto(["run_phase"])
Defensive patterns

Strategy: validation

Validate before calling

// Rust — pin the scheduler topology in CI; scheduler_graph_topology()
// compiles the exact same builder with stub effects.
#[test]
fn scheduler_graph_compiles() {
    let _ = scheduler_graph_topology()
        .expect("workflow scheduler graph must always compile");
}

Try / catch

// Treat as a programmer error, never a runtime condition to retry:
match build_scheduler_graph(n, select, run) {
    Ok(g) => g,
    Err(e) => {
        tracing::error!("scheduler topology bug: {e:#}");
        return Err(e);
    }
}

Prevention

When it happens

Trigger: Renaming a node in build_scheduler_graph without updating the matching with_goto strings; adding Command::default().with_goto(["new_node"]) without add_node("new_node", ...); pointing set_entry/set_finish at a removed node; a tinyagents upgrade that tightens compile-time topology validation.

Common situations: Refactors of workflow_runs/graph.rs (issue #4249 follow-ups); copy-pasted node blocks missing their add_node registration; CI breakage right after a tinyagents crate bump.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16). Data as JSON: /api/errors/25c35c6ff0648c67. Report an issue: GitHub.