espanso/espanso · critical
missing cli_args in worker main
Error message
missing cli_args in worker main
What it means
Immediately after paths, worker_main does args.cli_args.expect("missing cli_args in worker main"). The parsed clap arguments are attached by the dispatcher; the expect panics when cli_args was never populated. Like the missing-paths check, this is an internal contract violation of the CliModuleArgs wiring rather than a user-recoverable condition.
Source
Thrown at espanso/src/cli/worker/mod.rs:66
pub fn new() -> CliModule {
#[allow(clippy::needless_update)]
CliModule {
requires_paths: true,
requires_config: true,
requires_linux_capabilities: true,
enable_logs: true,
log_mode: super::LogMode::AppendOnly,
subcommand: "worker".to_string(),
entry: worker_main,
..Default::default()
}
}
fn worker_main(args: CliModuleArgs) -> i32 {
prevent_running_as_root_on_macos();
let paths = args.paths.expect("missing paths in worker main");
let cli_args = args.cli_args.expect("missing cli_args in worker main");
// When restarted, the daemon passes the reason why the worker was restarted (config_change, etc)
let start_reason = cli_args.value_of("start-reason").map(String::from);
debug!("starting with start-reason = {start_reason:?}");
// Avoid running multiple worker instances
let lock_file = acquire_worker_lock(&paths.runtime);
if lock_file.is_none() {
error!("worker is already running!");
return WORKER_ALREADY_RUNNING;
}
let config_store = args
.config_store
.expect("missing config store in worker main");
let match_store = args
.match_store
.expect("missing match store in worker main");View on GitHub (pinned to e6c3736675)
Solutions
- Make the dispatcher assign args.cli_args from the parsed clap matches before calling worker_main.
- Keep dispatch code in sync with the espanso version — re-apply local patches to the current dispatch flow.
- Invoke espanso through its normal CLI entry point rather than calling worker_main directly.
- Convert the expect into a clean error in custom builds.
Example fix
// before
let cli_args = args.cli_args.expect("missing cli_args in worker main");
// after
let cli_args = args.cli_args.ok_or_else(|| anyhow::anyhow!(
"missing cli_args in worker main: dispatcher did not pass parsed arguments"
))?; Defensive patterns
Strategy: type-guard
Type guard
fn require_cli_args(args: &CliModuleArgs) -> Result<&ArgMatches, String> {
args.cli_args.as_ref().ok_or_else(|| "missing cli_args in worker main".to_string())
} Try / catch
let cli_args = args.cli_args.ok_or_else(|| anyhow::anyhow!("missing cli_args in worker main"))?; Prevention
- Assign cli_args in the dispatcher before every worker_main call
- Cover the dispatch wiring with a smoke test that runs the worker subcommand
- Avoid invoking worker_main directly from tools or tests without full CliModuleArgs
When it happens
Trigger: worker_main called by the dispatch layer without first assigning args.cli_args from the parsed clap matches (wiring bug or custom entry point).
Common situations: Forked/patched builds with altered CLI dispatch; new subcommand plumbing that forgot to pass matches through; direct programmatic invocation of worker_main.
Related errors
- missing input, please specify the -i option
- missing input, please specify the -i option
- missing paths in worker main
- You need to specify the --trigger 'trigger' option. Run `esp
- missing package name
AI-assisted analysis of espanso/espanso@e6c3736675 (2026-09-06).
Data as JSON: /api/errors/e76c07f1dc6a45ff.
Report an issue: GitHub.