⚠️ 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.
Summary
PR #2974 (commit
8b3d481) wired the new--exit-when-nodes-finishflag intodora startby folding it into the descriptor before thehub: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 itsfingerprint_sourcehash — which thehub:path compares against the digest taken atdora buildtime. 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:177fingerprint_source(binaries/cli/src/session.rs:128) isserde_yaml::to_string(descriptor)hashed; the build-timesource_fingerprintwas computed from the descriptor with no such flag. The CLI arg isOption<bool>(Nonewhen omitted,Some(true)/Some(false)when given), andapply_exit_when_nodes_finishonly mutates when it'sSome.Concrete failure scenarios (hub dataflow, previously
dora build-ed)exit_when_nodes_finish, user runsdora start hubflow.yml --exit-when-nodes-finish: field goesNone → Some(true), serialization now includes the line, fingerprint mismatches → bails with the misleading "changed since the lastdora build" message. The flag can never take effect.exit_when_nodes_finish: true, user runsdora start hubflow.yml --exit-when-nodes-finish=false(the documented "force it off" override): field goesSome(true) → Some(false), fingerprint mismatches → bails the same way.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 runis unaffected — there the flag is applied inside the daemon after the resolved descriptor is used (binaries/daemon/src/lib.rs:1167-1185). Non-hubdora startis unaffected (the hub block is skipped, andinvalidate_if_build_inputs_changedfingerprints only build inputs, not this top-level field).Suggested fix
Move the
apply_exit_when_nodes_finishcall out of line 177 and apply it after the hub block and the build-input invalidation — right next toapply_env_overridesat line 242. That mirrors exactly how--envis 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 offingerprint_source.