Depends On
Last updated on October 28, 2026
You can control execution order between phases using the depends_on parameter.
main:
- name: Power On
key: power_on
python: phases.power_on
- name: Test WiFi
key: test_wifi
python: phases.test_wifi
depends_on: [power_on]
- name: Test Bluetooth
key: test_bluetooth
python: phases.test_bluetooth
depends_on: [power_on]
- name: Final Check
key: final_check
python: phases.final_check
depends_on: [test_wifi, test_bluetooth] TofuPilot waits for all dependencies to complete before executing a phase. Dependencies reference phase keys, not phase names.
Phases Without Dependencies
A phase without depends_on does not wait for the phase above it. TofuPilot starts phases in file order, as many at a time as there are free workers (8 by default). With fewer than 8 independent phases, they all start together.
For a bench where phases share one instrument or one link (a serial port, a MAVLink connection, a power supply), run them one after another, either with workers: 1 or by chaining depends_on:
execution:
workers: 1 # phases run one at a time, in file order (a retry waits its turn)When a phase fails under on_first_failure: stop (the default), phases that have not started are cancelled, phases already running finish, and teardown phases still run. See On Fail.
Validation
TofuPilot validates dependencies to prevent execution errors:
- Circular dependencies: Detects and prevents cycles (e.g., A waits for B, B waits for A) in setup, main and teardown
- Orphaned dependencies: Errors if a phase depends on a non-existent phase key, in any stage
- Later stage: Errors if a phase depends on a phase of a later stage (a setup phase waiting for a main phase, a shared
scope: executionsetup waiting for a per-slot setup) - Maximum dependencies: Each phase can have up to 100 dependencies
A dependency on an earlier stage is accepted and redundant: setup always completes before main, and main before teardown. A dependency on a phase further down the same stage is honoured: the order in the file does not matter.
The procedure lint (shown in Studio) also warns when a Python phase parameter without a default names another phase whose result it will not receive: one that is neither in its depends_on nor in an earlier stage, or, for a shared scope: execution setup or teardown phase, any per-slot phase (a shared phase only receives shared results). The warning says why the result is not available and what to change. The run would fail that phase at start; a parameter with a default receives its default instead (see Previous Results).
How is this guide?