# plan.Plan.run_over_control_mode

- **Module:** plan.Plan
- **Package:** libtmux
- **Language:** Rust
- **Kind:** method
- **Source:** https://github.com/libtmux/libtmux-rs/blob/f0e37052c232636b61d095817046e6bfc8f2ca40/crates/libtmux/src/plan/run.rs#L808
- **Page:** https://libtmux.org/en/rs/latest/reference/plan-plan-run_over_control_mode/

```
plan.Plan.run_over_control_mode(self, sender: &crate::control::ControlSender) -> Result<PlanResult, Error>
```

Run this plan over an open control-mode connection.

Control mode is the one transport that separates *how many commands*
from *how many processes*: every operation is its own protocol block
over one connection, so a plan costs one process however long it is and
every operation still reports its own outcome. That is the combination
a subprocess cannot offer -- there, sharing an invocation is what buys
the process back, and it is exactly what costs the attribution.

There is no planner argument because there is nothing to trade: blocks
are per command already.

# Errors

Returns an error when the connection is closed, a command cannot be
written, a slot dependency is invalid, or a creating operation does not
return valid IDs. Validation happens before the first command. A command
tmux refuses is reported in the [`PlanResult`].

Layouts are checked against the connected daemon's version before
any operation runs. Invalid or unsupported layouts return the same
errors as [`Window::select_layout`].

A plan holding a [`super::ops::Pause`] fails with
[`crate::ControlModeErrorKind::BlockingCommand`] before anything is
sent: tmux answers a delayed `run-shell` on a connection at once and
holds the next command instead, so the pause would report done before
it was.

# Cancel safety

The effect can be partial, as for [`Self::run`]: steps already sent
stay done, and the result naming them is lost with the future.
