Morganamilo/paru · error

no operation specified (use -h for help)

Error message

no operation specified (use -h for help)

What it means

handle_default handles paru invocations with no recognized operation flag. If targets were given, it degrades to an interactive sync (install) of those targets; otherwise there is literally nothing to do, so it bails with 'no operation specified', mirroring pacman's behavior.

Solutions

  1. Specify an operation and targets, e.g. `paru -S <pkg>` or `paru` alone is never enough
  2. Use `paru -Syu` for a full sync+upgrade, the most common intent
  3. If you wanted the interactive selector, pass targets: `paru <search-terms>`
  4. Check aliases/wrappers so operation flags aren't dropped

Example fix

// before
$ paru
no operation specified (use -h for help)
// after
$ paru -Syu    # or: paru firefox
Defensive patterns

Strategy: validation

Validate before calling

if op.is_none() && targets.is_empty() {
    eprintln!("usage: paru <operation> [targets]");
    std::process::exit(1);
}

Prevention

When it happens

Trigger: Running bare `paru` (or `paru` plus only options but no -S/-R/-Q/etc. operation and no targets) such that handle_cmd dispatches to handle_default with no targets and no op.

Common situations: Typing `paru` alone expecting an interactive menu; wrapping paru where the operation flag got lost (quoting/alias issues); scripts calling `paru $FLAGS` with FLAGS empty.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Morganamilo/paru@9ac3578807 (2026-09-12). Data as JSON: /api/errors/e9679ab5a26439d0. Report an issue: GitHub.

Appendix: source

Thrown at src/lib.rs:313

        let unneeded = util::unneeded_pkgs(config, !config.optional);
        if !unneeded.is_empty() {
            let mut args = config.pacman_args();
            args.remove("c").remove("clean");
            args.remove("o");
            args.targets = unneeded;
            args.op = "remove";
            Ok(exec::pacman(config, &args)?.code())
        } else {
            printtr!(" there is nothing to do");
            Ok(0)
        }
    } else if !config.targets.is_empty() {
        config.interactive = true;
        config.need_root = true;
        handle_sync(config).await?;
        Ok(0)
    } else {
        bail!(tr!("no operation specified (use -h for help)"));
    }
}

fn handle_remove(config: &mut Config) -> Result<i32> {
    remove::remove(config)
}

async fn handle_test(config: &Config) -> Result<i32> {
    if config.aur_filter {
        sync::filter(config).await
    } else {
        Ok(exec::pacman(config, &config.args)?.code())
    }
}

async fn handle_sync(config: &mut Config) -> Result<i32> {
    if config.targets.iter().any(|t| t.starts_with("./")) {
        let repo = PkgbuildRepo::from_cwd(config)?;

View on GitHub (pinned to 9ac3578807)