Running Scenarios Outside the Editor
A scenario you save in the Editor is an ordinary .json file. It can be run without the
Editor window open — with a single command, from a scheduler, or through Prefect. The robot
does exactly what you would see in the Editor; it simply draws nothing on screen.
| Need | Use |
|---|---|
| Scheduled runs while the Editor stays open on a workstation or VM | Orchestrator |
| Runs with no Editor window at all — CI, a server, an external scheduler | this page |
Running one command
Besides the scenario you need a robot profile — the one you save in the
Open Environment dialog, which is also a .json file.
aiviro-editor run --scenario invoices.json --profile robot_profile.json
Both options are required.
| Option | Effect |
|---|---|
--scenario PATH | The .json scenario to run. Required. |
--profile PATH | The robot profile to run it against. Required. |
--prod / --test | Production or test mode. --prod is the default, so a scenario runs live unless you pass --test. |
--run-log PATH | Writes a run-log .zip (action states plus logs) to that path. It opens in the Editor's log viewer via File → Open external log. |
Two options apply to the command as a whole and can also come from the environment:
| Option | Environment variable | Effect |
|---|---|---|
--log-to-console, -l | AIVIRO__LOG_TO_CONSOLE | Logs to the console — what you want in CI output. |
--debug | AIVIRO__DEBUG | Enables debug-only UI. Not useful headless. |
Running aiviro-editor with no subcommand launches the desktop GUI.
Exit codes
The command exits with 0 on success and 1 on failure, so it drops into any scheduler
or shell script. On failure it also prints Scenario failed: <summary> to standard error.
aiviro-editor run --scenario invoices.json --profile robot_profile.json --run-log run.zip || echo "failed"
Interactive actions do not work headless. A scenario containing Input Form fails with Interactive action encountered in headless mode — without a window there is nobody to ask. Gate such actions with Enabled (Test) so they never run in production.
Paths to the scenario and the profile can be absolute, or relative to the directory you run the command from.
Scheduled runs through Prefect
For recurring runs the scenario is wrapped in a Prefect flow. Copy this template into a file
under your project's flows/ directory — for example flows/flow_invoices.py — and adjust
the values listed below it.
import aiviro
from aiviro.modules.prefect_v3.storage import AiviroGitDockerStorage
from aiviro_editor.headless.runner import run_editor_scenario
from prefect import flow
from src import get_file_path, get_work_dir
SCENARIO_FILE = "scenarios/invoices.json"
PROFILE_FILE = "data/robot_profile.json"
@flow(log_prints=True, name="Invoice processing")
def main() -> None:
result = run_editor_scenario(
get_file_path(SCENARIO_FILE),
profile=get_file_path(PROFILE_FILE),
is_prod=True,
)
if not result.success:
raise RuntimeError("Scenario failed: " + result.error_summary)
if __name__ == "__main__":
main.from_source(
source=AiviroGitDockerStorage(project_path=get_work_dir(), git_branch="main"),
entrypoint="flows/flow_invoices.py:main",
).deploy(
name="main",
work_pool_name="aiviro-local",
work_queue_name="default",
cron="0 6 * * *",
job_variables={aiviro.AIVIRO_DEBUG_KEY: "0"},
)
What to change in your copy
| Value | Meaning |
|---|---|
SCENARIO_FILE, PROFILE_FILE | Paths to the scenario and the robot profile. Written from the project root, with forward slashes /, because the server reads them. |
name on @flow | The name the flow appears under in Prefect. |
entrypoint | Must match the file's location and name exactly, or the server will not find it. |
git_branch | The branch the scenario is taken from. |
cron | When to run. None means manual runs only. |
is_prod | True for a live run, False for a test run. |
The scenario and the profile must be saved in the project and committed to git — at run time the server reads them from there, not from your computer.
The Python API
run_editor_scenario is a one-shot wrapper and takes more than the template shows:
| Parameter | Meaning |
|---|---|
scenario | Path to the .json, or an already loaded scenario. |
profile | Path to the profile, or a loaded profile object. |
robot | An existing robot to run against, instead of profile. Exactly one of profile / robot must be given. |
is_prod | True (default) for production, False for test. |
run_log_path | Where to write the run-log .zip. |
wait_after | Seconds to wait after the scenario finishes. |
It returns a result with success, error_summary and run_log_path.
To run several scenarios against one robot, use EditorRunner directly instead of
calling run_editor_scenario repeatedly — it connects the robot once and reuses it, which
saves the whole connection and start-up cost per scenario.
Checklist before going headless
- Every credential is in the Vault, and the keys exist on the machine that will run the scenario.
- No Input Form or other interactive action runs in production.
- The scenario ends with reporting — see Make the scenario survive unattended runs.
--run-logis set, so a failed run leaves something to read.- The robot profile on the target machine has the right address, credentials and display.