warpdotdev/warp · error · anyhow::Error

Multiple runners match '{name}'; specify the runner by UID

Error message

Multiple runners match '{name}'; specify the runner by UID

What it means

Ambiguity branch of the same runner-by-name resolver: filtering the fetched runners by config.name yielded two or more entries. Runner names are not unique server-side, so a name alone cannot identify which runner to mutate and the command refuses to guess. The message tells you to disambiguate with the runner UID.

Source

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

    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,
            Some(MacOsConfigInput {
                version: args.macos_version.map(macos_version_to_gql),

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Get the UID of the intended runner from the runner list and pass it instead of --name
  2. Rename the duplicate runners so names are unique within the visible set
  3. Scope the command to the owning team so only one match is visible, if the CLI supports owner selection

Example fix

// before
oz runner update --name build --memory-gb 8
# Error: Multiple runners match 'build'; specify the runner by UID

// after
oz runner list                 # two rows named 'build'; pick the right UID
oz runner update --uid rnr_abc123 --memory-gb 8
Defensive patterns

Strategy: validation

Validate before calling

let matches: Vec<_> = runners.iter().filter(|r| r.config.name == name).collect();
if matches.len() != 1 {
    anyhow::bail!("expected exactly one runner named '{name}', found {}", matches.len());
}
update_runner(matches[0].uid.clone(), input).await?;

Type guard

fn unique_runner_by_name<'a>(runners: &'a [Runner], name: &str) -> Option<&'a Runner> {
    let m: Vec<_> = runners.iter().filter(|r| r.config.name == name).collect();
    (m.len() == 1).then(|| m[0])
}

Prevention

When it happens

Trigger: Two or more runners visible to the current owner share the same config.name (e.g. created independently in different teams), and a runner command is invoked with --name only.

Common situations: Provisioning templates that create runners with a fixed name run in multiple teams; duplicates after a team merge or rename; shared org-wide runner names.

Related errors


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