warpdotdev/warp · error · anyhow::Error

Runner ' ' not found

Error message

Runner '{name}' not found

What it means

Thrown by the agent SDK runner resolver when a command selects a runner by --name but no runner in the fetched server-side list has that exact config.name. The resolver filters the runner list after fetching it from the server, so the name must match exactly (case-sensitive) a runner visible to the current owner. This is the empty-match branch; one match returns the runner and multiple matches raise a separate ambiguity error.

Solutions

  1. Run the runner list subcommand for the current owner and copy the exact name (check casing)
  2. Pass the runner UID instead of the name; UIDs are unique and avoid both not-found and ambiguity errors
  3. Verify you are targeting the right owner/team scope so the runner appears in the fetched list
  4. If the runner was recently created or renamed, re-run after the runner list syncs

Example fix

// before
oz runner update --name Ci-Runner --memory-gb 8
# Error: Runner 'Ci-Runner' not found

// after
oz runner list                 # copy exact name and uid
oz runner update --name ci-runner --memory-gb 8
# or uniquely:
oz runner update --uid rnr_abc123 --memory-gb 8
Defensive patterns

Strategy: validation

Validate before calling

let runners = fetch_runners(&owner).await?;
if !runners.iter().any(|r| r.config.name == name) {
    anyhow::bail!(
        "no runner named '{name}'; known: {}",
        runners.iter().map(|r| r.config.name.as_str()).collect::<Vec<_>>().join(", ")
    );
}
update_runner_by_name(name, input).await?;

Type guard

fn runner_name_exists(runners: &[Runner], name: &str) -> bool {
    runners.iter().any(|r| r.config.name == name)
}

Prevention

When it happens

Trigger: Running a runner subcommand with --name <name> (e.g. an update command) where zero fetched runners have config.name == name: typo, different casing, the runner was deleted, or it belongs to another owner/team not included in the fetched list.

Common situations: Runner renamed or deleted from another machine and an old command re-run; CI scripts hard-coding a runner name; assuming names are case-insensitive or fuzzy-matched; runner list not yet synced after an account or team switch.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/ce45f6bbd8cd819a. Report an issue: GitHub.

Appendix: source

Thrown at app/src/ai/agent_sdk/runner.rs:243

fn resolve_runner<'a>(
    runners: &'a [Runner],
    id: Option<&str>,
    name: Option<&str>,
) -> Result<&'a Runner> {
    if let Some(id) = id {
        return runners
            .iter()
            .find(|runner| runner.uid.inner() == id)
            .ok_or_else(|| anyhow!("Runner '{id}' not found"));
    }

    let name = name.ok_or_else(|| anyhow!("A runner UID or --name is required"))?;
    let matches: Vec<&Runner> = runners
        .iter()
        .filter(|runner| runner.config.name == name)
        .collect();
    match matches.as_slice() {
        [] => Err(anyhow!("Runner '{name}' not found")),
        [runner] => Ok(runner),
        _ => Err(anyhow!(
            "Multiple runners match '{name}'; specify the runner by UID"
        )),
    }
}

/// Build the [`RunnerInput`] for a create operation.
fn build_create_input(args: CreateRunnerArgs, owner: GqlOwner) -> UpsertRunnerInput {
    let os = os_to_gql(args.os);
    let (linux, mac) = match args.os {
        RunnerOsArg::Linux => (
            args.docker_image
                .map(|docker_image| LinuxConfigInput { docker_image }),
            None,
        ),
        RunnerOsArg::Macos => (
            None,

View on GitHub (pinned to e72fd7aacb)