{"record":{"id":"56dc8d9e4a946c45","repo":"warpdotdev/warp","slug":"memory-gb-is-required-when-setting-an-instance-s","errorCode":null,"errorMessage":"--memory-gb is required when setting an instance shape for a runner that has none","messagePattern":"--memory-gb is required when setting an instance shape for a runner that has none","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"app/src/ai/agent_sdk/runner.rs","lineNumber":393,"sourceCode":"}\n\n/// Merge instance-shape overrides with the existing shape (`(vcpus, memory_gb)`),\n/// allowing vCPUs and memory to be updated independently. Returns `None` when\n/// there is no shape to set, or an error when only one dimension is provided for\n/// a runner that has no existing shape to supply the other.\nfn merge_instance_shape(\n    new_vcpus: Option<i32>,\n    new_memory_gb: Option<i32>,\n    existing: Option<(i32, i32)>,\n) -> Result<Option<(i32, i32)>> {\n    if new_vcpus.is_none() && new_memory_gb.is_none() {\n        return Ok(existing);\n    }\n    let vcpus = new_vcpus.or(existing.map(|(v, _)| v)).ok_or_else(|| {\n        anyhow!(\"--vcpus is required when setting an instance shape for a runner that has none\")\n    })?;\n    let memory_gb = new_memory_gb.or(existing.map(|(_, m)| m)).ok_or_else(|| {\n        anyhow!(\"--memory-gb is required when setting an instance shape for a runner that has none\")\n    })?;\n    Ok(Some((vcpus, memory_gb)))\n}\n\nfn os_to_gql(os: RunnerOsArg) -> RunnerOs {\n    match os {\n        RunnerOsArg::Linux => RunnerOs::Linux,\n        RunnerOsArg::Macos => RunnerOs::Macos,\n    }\n}\n\n/// Resolve a [`RunnerArchArg`] into a concrete [`RunnerArch`], mapping `auto`\n/// to the default architecture for the given OS (x86-64 on Linux, aarch64 on\n/// macOS).\nfn resolve_arch(arch: RunnerArchArg, os: RunnerOsArg) -> RunnerArch {\n    match arch {\n        RunnerArchArg::X8664 => RunnerArch::X8664,\n        RunnerArchArg::Aarch64 => RunnerArch::Aarch64,","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/app/src/ai/agent_sdk/runner.rs#L375-L411","documentation":"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.","triggerScenarios":"oz runner update --vcpus 4 (memory flag absent) on a runner with no existing instance shape, so memory_gb cannot be inherited from existing.","commonSituations":"Scaling CPU only on a new shapeless runner; partial flag sets from scripts; assuming memory defaults to a standard size.","solutions":["Pass both dimensions together: --vcpus N --memory-gb M","Set a complete shape first, then single-dimension updates work by inheriting the other value"],"exampleFix":"// before\noz runner update --uid rnr_x --vcpus 4\n# Error: --memory-gb is required when setting an instance shape for a runner that has none\n\n// after\noz runner update --uid rnr_x --vcpus 4 --memory-gb 8","handlingStrategy":"validation","validationCode":"let existing: Option<(i32, i32)> = runner.instance_shape();\nif existing.is_none() && (vcpus.is_some() ^ memory_gb.is_some()) {\n    anyhow::bail!(\"shapeless runner: pass both --vcpus and --memory-gb\");\n}\nmerge_instance_shape(vcpus, memory_gb, existing)?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat (vcpus, memory_gb) as one atomic unit in provisioning scripts","Check the runner's current shape before one-sided updates","Keep full-shape commands in runbooks, not partial ones"],"tags":["agent-sdk","runner","cli","instance-shape","validation"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}