warpdotdev/warp · error · anyhow::Error

--memory-gb is required when setting an instance shape for a

Error message

--memory-gb is required when setting an instance shape for a runner that has none

What it means

Mirror of the --vcpus case in merge_instance_shape: an update provided --vcpus but not --memory-gb, and the runner has no existing shape to supply the memory dimension. The function refuses to invent a memory value, so the whole update fails before any request is sent.

Source

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

}

/// Merge instance-shape overrides with the existing shape (`(vcpus, memory_gb)`),
/// allowing vCPUs and memory to be updated independently. Returns `None` when
/// there is no shape to set, or an error when only one dimension is provided for
/// a runner that has no existing shape to supply the other.
fn merge_instance_shape(
    new_vcpus: Option<i32>,
    new_memory_gb: Option<i32>,
    existing: Option<(i32, i32)>,
) -> Result<Option<(i32, i32)>> {
    if new_vcpus.is_none() && new_memory_gb.is_none() {
        return Ok(existing);
    }
    let vcpus = new_vcpus.or(existing.map(|(v, _)| v)).ok_or_else(|| {
        anyhow!("--vcpus is required when setting an instance shape for a runner that has none")
    })?;
    let memory_gb = new_memory_gb.or(existing.map(|(_, m)| m)).ok_or_else(|| {
        anyhow!("--memory-gb is required when setting an instance shape for a runner that has none")
    })?;
    Ok(Some((vcpus, memory_gb)))
}

fn os_to_gql(os: RunnerOsArg) -> RunnerOs {
    match os {
        RunnerOsArg::Linux => RunnerOs::Linux,
        RunnerOsArg::Macos => RunnerOs::Macos,
    }
}

/// Resolve a [`RunnerArchArg`] into a concrete [`RunnerArch`], mapping `auto`
/// to the default architecture for the given OS (x86-64 on Linux, aarch64 on
/// macOS).
fn resolve_arch(arch: RunnerArchArg, os: RunnerOsArg) -> RunnerArch {
    match arch {
        RunnerArchArg::X8664 => RunnerArch::X8664,
        RunnerArchArg::Aarch64 => RunnerArch::Aarch64,

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Pass both dimensions together: --vcpus N --memory-gb M
  2. Set a complete shape first, then single-dimension updates work by inheriting the other value

Example fix

// before
oz runner update --uid rnr_x --vcpus 4
# Error: --memory-gb is required when setting an instance shape for a runner that has none

// after
oz runner update --uid rnr_x --vcpus 4 --memory-gb 8
Defensive patterns

Strategy: validation

Validate before calling

let existing: Option<(i32, i32)> = runner.instance_shape();
if existing.is_none() && (vcpus.is_some() ^ memory_gb.is_some()) {
    anyhow::bail!("shapeless runner: pass both --vcpus and --memory-gb");
}
merge_instance_shape(vcpus, memory_gb, existing)?;

Prevention

When it happens

Trigger: oz runner update --vcpus 4 (memory flag absent) on a runner with no existing instance shape, so memory_gb cannot be inherited from existing.

Common situations: Scaling CPU only on a new shapeless runner; partial flag sets from scripts; assuming memory defaults to a standard size.

Related errors


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