From da1e5e1ba872c4b191fb67ad4478ba1250cbdf30 Mon Sep 17 00:00:00 2001 From: claude Date: Wed, 27 May 2026 15:21:43 -0400 Subject: [PATCH] fix(smolmachines): pass --net explicitly when allow_cidrs is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit smolvm 0.8.0 docs say `--allow-cidr` implies `--net`, but empirically the implication only fires when no `--from` is set. `--from PATH --allow-cidr X/32` silently produces a machine with network: false and no routes in the guest — claude lands inside with HTTPS_PROXY pointing at the bundle's pinned IP but every connect fails with "Network is unreachable" / FailedToOpenSocket in claude's UI. Reproduce + verify: $ smolvm machine create --from --allow-cidr X/32 nettest $ smolvm machine ls --json | jq '.[].network' # false $ smolvm machine create --from --net --allow-cidr X/32 nettest2 $ smolvm machine ls --json | jq '.[].network' # true Add `--net` whenever `allow_cidrs` is non-empty. No change to the no-allow-cidr code path. Test added to lock down both branches. Co-Authored-By: Claude Opus 4.7 --- claude_bottle/backend/smolmachines/smolvm.py | 11 ++++++++++- tests/unit/test_smolmachines_smolvm.py | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/claude_bottle/backend/smolmachines/smolvm.py b/claude_bottle/backend/smolmachines/smolvm.py index c836cfe..c3ada06 100644 --- a/claude_bottle/backend/smolmachines/smolvm.py +++ b/claude_bottle/backend/smolmachines/smolvm.py @@ -117,12 +117,21 @@ def machine_create( Smolfile because `--from` and `--smolfile` are themselves mutually exclusive in smolvm 0.8.0 — and we want `--from`'s no-pull-at-start property. The flag form gives the same - result without the Smolfile complication.""" + result without the Smolfile complication. + + `--net` is sent explicitly when `allow_cidrs` is non-empty. + smolvm 0.8.0's docs say `--allow-cidr` implies `--net`, but + empirically the implication only fires when no `--from` is + set — `--from PATH --allow-cidr X/32` silently produces a + machine with `network: false` and no routes in the guest, so + the agent can't reach the bundle's pinned IP.""" args: list[str] = ["machine", "create"] if image is not None: args += ["--image", image] if from_path is not None: args += ["--from", str(from_path)] + if allow_cidrs: + args.append("--net") for cidr in allow_cidrs: args += ["--allow-cidr", cidr] if env: diff --git a/tests/unit/test_smolmachines_smolvm.py b/tests/unit/test_smolmachines_smolvm.py index 02bdc90..b8ef49a 100644 --- a/tests/unit/test_smolmachines_smolvm.py +++ b/tests/unit/test_smolmachines_smolvm.py @@ -82,12 +82,20 @@ class TestArgvShapes(unittest.TestCase): self.assertEqual("smolvm", argv[0]) self.assertIn("--from", argv) self.assertIn("/stage/agent.smolmachine", argv) + # `--net` is explicit because smolvm 0.8.0's implied-net + # from --allow-cidr doesn't fire when --from is set. + self.assertIn("--net", argv) self.assertIn("--allow-cidr", argv) self.assertIn("192.168.50.2/32", argv) self.assertIn("-e", argv) self.assertIn("HTTPS_PROXY=http://192.168.50.2:8888", argv) self.assertEqual("agent-xyz", argv[-1]) + def test_machine_create_omits_net_when_no_allow_cidrs(self): + with self._patch_run() as m: + machine_create("agent-xyz", from_path=Path("/x.smolmachine")) + self.assertNotIn("--net", m.call_args.args[0]) + def test_machine_start_uses_dash_name(self): # `start` is the --name flag form, NOT positional. with self._patch_run() as m: