Skip to content

fix(sandbox): explain a QEMURuntime mode/argument mismatch (#3160) - #3166

Open
r33drichards wants to merge 1 commit into
mainfrom
fix/3160-qemu-runtime-mode-kwargs
Open

fix(sandbox): explain a QEMURuntime mode/argument mismatch (#3160)#3166
r33drichards wants to merge 1 commit into
mainfrom
fix/3160-qemu-runtime-mode-kwargs

Conversation

@r33drichards

Copy link
Copy Markdown
Collaborator

Fixes #3160.

QEMURuntime(mode: str = "docker", **kwargs) routes to QEMUDockerRuntime, whose constructor has no extra_args. extra_args is how -cpu host is passed — the documented fix for the commonest local failure in the Minecraft how-to (the game exiting during resource loading under the default qemu64 model). So the most natural call fails with a type error about a class the caller never named:

TypeError: QEMUDockerRuntime.__init__() got an unexpected keyword argument 'extra_args'

Nothing in that mentions mode, which is the knob that actually decides.

What this does

The factory validates the passed kwargs against the constructor of the selected mode and reports the mismatch in the caller's own vocabulary:

>>> QEMURuntime(extra_args=["-cpu", "host"])
TypeError: QEMURuntime(mode='docker') does not accept: extra_args (accepted by
mode='bare-metal' or mode='wsl2'). Raw QEMU flags such as -cpu host go in
extra_args, which only the modes that build the QEMU command line themselves
accept; mode='docker' (the default) runs a prebuilt image whose command line is
fixed.

>>> QEMURuntime(mode="bare-metal", vnc_port=1)
TypeError: QEMURuntime(mode='bare-metal') does not accept: vnc_port (accepted by mode='docker').

>>> QEMURuntime(mode="baremetal")
ValueError: Unknown QEMURuntime mode 'baremetal'; expected one of 'docker', 'bare-metal', 'wsl2'

The accepted names come from inspect.signature of each runtime, so the modes cannot drift apart from the message. The unknown-mode check is the same defect one layer up: mode="baremetal" used to fall through to Docker in silence.

Why this option and not the others

  • Catching the TypeError and re-raising would fix the wording and nothing else — the message would still be assembled from whatever CPython happened to say, and mode="baremetal" would still silently give you Docker.
  • Accept and ignore is the worst outcome for this particular flag: a caller who passes -cpu host and gets a VM booted without it sees the exact Minecraft failure they were trying to fix, with no error to explain it.
  • Dispatch on capability (let extra_args select bare-metal by itself) changes which backend runs for an existing caller without being asked. bare-metal is not a drop-in substitute for docker — it needs qemu-system-* on PATH and a disk image on disk — so guessing here trades a clear error for an obscure boot failure.

The default mode is unchanged. Every QEMURuntime( call site in the repo was checked against the new validation:

libs/python/cua-sandbox/cua_sandbox/sandbox.py:288 mode='docker'     kwargs=[] -> OK
libs/python/cua-sandbox/cua_sandbox/sandbox.py:255 mode='bare-metal' kwargs=[] -> OK
...
tests/integration/sandbox_sdk/test_linux_local_osworld_vm.py:76 mode='bare-metal' kwargs=['api_port', 'cpu_count', 'memory_mb', 'vnc_display'] -> OK

call sites that would newly raise: 0

Test

libs/python/cua-sandbox/tests/test_qemu_runtime_modes.py. It fails on main's runtime source — stashing only the source file, keeping the test:

$ git stash push -- libs/python/cua-sandbox/cua_sandbox/runtime/qemu.py
$ uv run --frozen python -m pytest tests/test_qemu_runtime_modes.py -q
E  assert "mode='docker'" in "QEMUDockerRuntime.__init__() got an unexpected keyword argument 'extra_args'"
E  Failed: DID NOT RAISE ValueError
2 failed, 4 passed

and passes with it restored (6 passed). One case covers the default backend explicitly, so a later change to the default breaks a test instead of breaking callers quietly.

🤖 Generated with Claude Code

QEMURuntime(mode="docker") is the default and routes to QEMUDockerRuntime, whose
constructor has no extra_args. extra_args is how -cpu host is passed, the
documented fix for the commonest local failure in the Minecraft how-to, so

    QEMURuntime(extra_args=["-cpu", "host"])

failed with "QEMUDockerRuntime.__init__() got an unexpected keyword argument
'extra_args'" — a class the caller never mentioned, and no hint that mode is
what selects it.

The factory now validates kwargs against the constructor of the selected mode
and reports the mismatch in the caller's own vocabulary:

    QEMURuntime(mode='docker') does not accept: extra_args (accepted by
    mode='bare-metal' or mode='wsl2'). Raw QEMU flags such as -cpu host go in
    extra_args, which only the modes that build the QEMU command line
    themselves accept; mode='docker' (the default) runs a prebuilt image whose
    command line is fixed.

The accepted names are read from each runtime's signature, so the three modes
cannot drift apart from the message. An unknown mode string is also rejected
now: mode="baremetal" previously fell through to Docker in silence, which is
the same defect one layer up.

Deliberately not done: dispatching on capability, i.e. letting extra_args
select bare-metal on its own. That would swap the backend under existing
callers without being asked, and bare-metal is not a drop-in substitute — it
needs qemu-system-* on PATH and a disk image on disk. The default mode is
unchanged; every QEMURuntime call site in the repo was checked against the new
validation and none of them raises.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sandbox: QEMURuntime defaults to docker, where extra_args is rejected

2 participants