Skip to content

cli: dora start --exit-when-nodes-finish is broken for hub: dataflows — spurious "changed since the last dora build" bail (or silently dropped override) #2996

Description

@phil-opp

⚠️ This issue was created by a scheduled, automated Claude code-review check. It was not filed by a human. Please verify the finding before acting on it.

Summary

PR #2974 (commit 8b3d481) wired the new --exit-when-nodes-finish flag into dora start by folding it into the descriptor before the hub: build-fingerprint check. Because the descriptor field is #[serde(default, skip_serializing_if = "Option::is_none")], applying a value that differs from the on-disk YAML changes the serialized descriptor and therefore its fingerprint_source hash — which the hub: path compares against the digest taken at dora build time. The result: on a hub dataflow, using the flag either aborts with a misleading "changed since build" error or is silently dropped. The override is effectively unusable there.

Location

binaries/cli/src/command/start/mod.rs:177

// line 177 — applied too early
dataflow_descriptor.apply_exit_when_nodes_finish(exit_when_nodes_finish);// line 186-198 — hub fingerprint gate runs AFTER, and now sees the changed field
if dataflow_descriptor.nodes.iter().any(|n| n.hub.is_some()) {
    let resolved = dataflow_session.resolved_dataflow.clone()...;
    let current = DataflowSession::fingerprint_source(&dataflow_descriptor); // includes the flag now
    if current.is_none() || current != dataflow_session.source_fingerprint {
        eyre::bail!("this dataflow changed since the last `dora build` — run `dora build` again …");
    }
    dataflow_descriptor = resolved;   // also overwrites, dropping the applied flag
}

fingerprint_source (binaries/cli/src/session.rs:128) is serde_yaml::to_string(descriptor) hashed; the build-time source_fingerprint was computed from the descriptor with no such flag. The CLI arg is Option<bool> (None when omitted, Some(true)/Some(false) when given), and apply_exit_when_nodes_finish only mutates when it's Some.

Concrete failure scenarios (hub dataflow, previously dora build-ed)

  • YAML has no exit_when_nodes_finish, user runs dora start hubflow.yml --exit-when-nodes-finish: field goes None → Some(true), serialization now includes the line, fingerprint mismatches → bails with the misleading "changed since the last dora build" message. The flag can never take effect.
  • YAML has exit_when_nodes_finish: true, user runs dora start hubflow.yml --exit-when-nodes-finish=false (the documented "force it off" override): field goes Some(true) → Some(false), fingerprint mismatches → bails the same way.
  • Even if the fingerprint happened to match, line 197 (dataflow_descriptor = resolved) replaces the descriptor with the build-time resolved form, discarding the CLI-applied flag.

Net effect: on hub dataflows the override only "works" when it agrees with what the YAML already says (i.e. does nothing). dora run is unaffected — there the flag is applied inside the daemon after the resolved descriptor is used (binaries/daemon/src/lib.rs:1167-1185). Non-hub dora start is unaffected (the hub block is skipped, and invalidate_if_build_inputs_changed fingerprints only build inputs, not this top-level field).

Suggested fix

Move the apply_exit_when_nodes_finish call out of line 177 and apply it after the hub block and the build-input invalidation — right next to apply_env_overrides at line 242. That mirrors exactly how --env is deliberately merged last, with the existing comment (lines 236-241) explaining that a spawn-time input must not be part of the build fingerprint. This applies the flag to the final (hub-resolved) descriptor and keeps it out of fingerprint_source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcliCLIdaemondocumentationImprovements or additions to documentationrust

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions